为什么这段代码
long s, e, sum1 = 0, sum2 = 0, TRIALS = 10000000;
for(long i=0; i<TRIALS; i++) {
s = System.nanoTime();
e = System.nanoTime();
sum1 += e - s;
s = System.nanoTime();
e = System.nanoTime();
sum2 += e - s;
}
System.out.println(sum1 / TRIALS);
System.out.println(sum2 / TRIALS);
产生此结果
-60
61
“在我的机器上?”
编辑:
Sam I am's answer指向nanoSecond()文档,这有助于,但现在,更准确地说,为什么结果始终有利于第一笔总和?
“我的机器”:
JavaSE-1.7,Eclipse
赢得7 x64,AMD Athlon II X4 635
在循环内切换顺序会产生反向结果
for(int i=0; i<TRIALS; i++) {
s = System.nanoTime();
e = System.nanoTime();
sum2 += e - s;
s = System.nanoTime();
e = System.nanoTime();
sum1 += e - s;
}
61
-61
在将它添加到sum1之前查找(e-s)使得sum1为正。
for(long i=0; i<TRIALS; i++) {
s = System.nanoTime();
e = System.nanoTime();
temp = e-s;
if(temp < 0)
count++;
sum1 += temp;
s = System.nanoTime();
e = System.nanoTime();
sum2 += e - s;
}
61
61
正如Andrew Alcock指出的那样,sum1 + = -s + e会产生预期的结果。
for(long i=0; i<TRIALS; i++) {
s = System.nanoTime();
e = System.nanoTime();
sum1 += -s + e;
s = System.nanoTime();
e = System.nanoTime();
sum2 += -s + e;
}
61
61
其他一些测试:http://pastebin.com/QJ93NZxP
答案 0 :(得分:2)
这个答案是假设。如果您使用有关您的环境的一些详细信息更新您的问题,那么其他人可能会提供更详细的基础答案。
nanoTime()
功能通过访问具有低访问延迟的某些高分辨率计时器来工作。在x86上,我相信这是Time Stamp Counter,它是由机器的基本时钟周期驱动的。
如果你看到+/- 60 ns的一致结果,那么我相信你只是看到机器上计时器的基本间隔。
然而,负数呢?同样,假设,但如果您阅读维基百科文章,您会看到英特尔处理器可能会重新订购说明的评论。
答案 1 :(得分:1)
与roundar一起,我们对此代码进行了大量测试。总之,在以下情况下效果消失了:
sum += e - s
更改为sum += -s + e
此外,效果不是线程:
效果不是时间问题,因为:
鉴于上述情况,我相信我们在Java VM的热点模块中有一个错误。写为的代码应返回正结果,但不会。
答案 2 :(得分:0)
简而言之:更新值的频率可能导致结果不同。
nanoTime
public static long nanoTime()
返回最精确的可用系统计时器的当前值,以纳秒为单位。
此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。
返回的值表示自固定但任意时间以来的纳秒 (也许在未来,所以价值观可能是负面的)。这种方法 提供纳秒级精度,但不一定是纳秒级 准确性。不保证值的变化频率。 连续调用的差异大于约 292年(263纳秒)将无法准确计算经过的时间 由于数字溢出。
For example, to measure how long some code takes to execute: long startTime = System.nanoTime(); // ... the code being measured ... long estimatedTime = System.nanoTime() - startTime; Returns: The current value of the system timer, in nanoseconds. Since: 1.5