我正在选修算法和算法分析课程。我想知道一个简单的操作-- +
,-
,/
,*
--能对我的电脑起多大作用。所以我写了一个简单的秒表如下:
public class NanosecondsStopWatch implements StopWatch {
private PrintStream stream;
public NanosecondsStopWatch(PrintStream stream) {
this.stream = stream;
}
@Override
public void timeAndPrint(Action action) {
long start = System.nanoTime();
action.doAction();
long end = System.nanoTime();
stream.println(end-start);
}
}
public class TestingOperationsTime {
public static void main(String[] strings) {
StopWatch watch = new NanosecondsStopWatch(System.out);
watch.timeAndPrint(new Action() {
@Override
public void doAction() {
int i= 2*2;
}
});
watch.timeAndPrint(new Action() {
@Override
public void doAction() {
int i= 2/2;
}
});
watch.timeAndPrint(new Action() {
@Override
public void doAction() {
int i= 2-2;
}
});
watch.timeAndPrint(new Action() {
@Override
public void doAction() {
int i= 2+2;
}
});
}
}
结果如下:
2529
454
355
335
但是,如果我更改操作的顺序,请这样说:
public class TestingOperationsTime {
public static void main(String[] strings) {
StopWatch watch = new NanosecondsStopWatch(System.out);
watch.timeAndPrint(new Action() {
@Override
public void doAction() {
int i= 2-2;
}
});
watch.timeAndPrint(new Action() {
@Override
public void doAction() {
int i= 2*2;
}
});
watch.timeAndPrint(new Action() {
@Override
public void doAction() {
int i= 2/2;
}
});
watch.timeAndPrint(new Action() {
@Override
public void doAction() {
int i= 2+2;
}
});
}
}
结果仍然是几乎一样的:
2494
332
309
326
你怎么解释这种行为?
发布于 2014-09-15 21:28:15
有许多因素影响您的代码使用的系统时间。例如,如果计算机在运行代码时执行上下文切换,则所获得的时间包括运行另一个程序所花费的时间。
为了缓解这种情况,您可以多次运行定时器,比如数千次或数百万次,并取平均值。
此外,正如@rgettman所指出的,编译器很可能会优化这些计算,因为它们是在常量值上执行的。这意味着您只是在计时调用方法和打印输出的开销,而不是执行计算的时间。
发布于 2014-09-15 21:28:06
总是会有差异,因为您的计算机上还有其他进程在运行,并且取决于操作系统,某些进程将优先于其他进程。您无法准确预测单个操作所需的毫秒数。这也取决于您在计算机中CPU的速度。
发布于 2014-09-15 21:29:33
编译器在编译时计算常量表达式,应该使其成为接收参数的方法。
其次,对手表的系统调用需要超过几个纳米秒,所以这个检查永远不会被感知到,实际上您得到的是java获取时间所需的时间。
https://stackoverflow.com/questions/25857129
复制相似问题