我在这里遇到了一个不寻常的真正发行后测量时间的流逝减少。似乎调用Thread.sleep(n),其中n> 0会导致以下System.nanoTime()调用的可预测性较差。精度System.nanoTime()来给了Thread.sleep()的调用
下面的代码演示了这个问题。
我的计算机上运行它(RMBP 15" 2015年,OS X 10.11,JRE 1.8.0_40-B26)输出以下结果:
Control: 48497
Random: 36719
Thread.sleep(0): 48044
Thread.sleep(1): 832271
在运行Windows 8(VMware的地平线时,Windows虚拟机8.1,是1.8.0_60-B27):
Control: 98974
Random: 61019
Thread.sleep(0): 115623
Thread.sleep(1): 282451
然而,企业服务器上运行它(VMware的,RHEL 6.7,JRE 1.6.0_45-B06):
Control: 1385670
Random: 1202695
Thread.sleep(0): 1393994
Thread.sleep(1): 1413220
这是令人惊讶的结果我期望。
显然Thread.sleep代码(1)影响下面的代码的计算。我不知道为什么会发生这种情况。有人有线索吗?
谢谢!
public class Main {
public static void main(String[] args) {
int N = 1000;
long timeElapsed = 0;
long startTime, endTime = 0;
for (int i = 0; i < N; i++) {
startTime = System.nanoTime();
//search runs here
endTime = System.nanoTime();
timeElapsed += endTime - startTime;
}
System.out.println("Control: " + timeElapsed);
timeElapsed = 0;
for (int i = 0; i < N; i++) {
startTime = System.nanoTime();
//search runs here
endTime = System.nanoTime();
timeElapsed += endTime - startTime;
for (int j = 0; j < N; j++) {
int k = (int) Math.pow(i, j);
}
}
System.out.println("Random: " + timeElapsed);
timeElapsed = 0;
for (int i = 0; i < N; i++) {
startTime = System.nanoTime();
//search runs here
endTime = System.nanoTime();
timeElapsed += endTime - startTime;
try {
Thread.sleep(0);
} catch (InterruptedException e) {
break;
}
}
System.out.println("Thread.sleep(0): " + timeElapsed);
timeElapsed = 0;
for (int i = 0; i < N; i++) {
startTime = System.nanoTime();
//search runs here
endTime = System.nanoTime();
timeElapsed += endTime - startTime;
try {
Thread.sleep(2);
} catch (InterruptedException e) {
break;
}
}
System.out.println("Thread.sleep(1): " + timeElapsed);
}
}
基本上我在一个while循环内运行搜索,每次迭代都需要通过调用Thread.sleep()来休息一下。我想排除运行搜索所花费的总时间中的睡眠时间,所以我使用System.nanoTime()来记录开始和结束时间。但是,正如您在上面注意到的那样,这样做效果不佳。
有没有办法来解决这个问题?
感谢任何投入!
嗨@TheLima,我明白你的意思。这只是我面临的问题的一个随意演示。您可以根据需要放置尽可能多的代码,并且您仍然会注意到相同的结果:Thread.sleep()确实增加了两次System.nanoTime()调用之间的时间。 –
您的代码在解释帧中执行。你真的想衡量翻译速度吗?将整个'main'主体移到单独的方法中,并在循环中调用它100次。随后的调用结果将会有很大的不同。 –
我编辑了OP,添加了与正在做什么相关的重要注释;因为如果没有它们,那么可能会有,并且*有*混淆.......................并且将'startTime'和'endTime'变量移出循环,因为使许多不必要的分配应被视为资本罪。 = P – XenoRo