用Java测量时间

dev*_*ium 4 java performance time profiling

所以我试图测量两个不同的算法实现完成给定任务所花费的时间,结果如下:

i    alg1  alg2
4   0.002   0.0
5   0.001   0.0
6   0.003   0.002
7   0.023   0.01
8   0.055   0.041
9   0.056   0.0
10  0.208   0.101
11  1.767   0.694
12  18.581  7.784
Run Code Online (Sandbox Code Playgroud)

i只是一些输入参数.

我已经使用以下(天真)函数测量了算法的性能:

private double getDuration() {
    return (double)(System.currentTimeMillis() - startTime) / (double)1000;
}
Run Code Online (Sandbox Code Playgroud)

获得更多真实结果(除了0.0,显然不是真的!)的优选方法是System.currentTimeMillis()什么?我知道我可以只运行算法,一遍又一遍,总结他们的结果,但我有这样的感觉:有可能是测量时间的流逝在Java中的一些更健壮的方式(包括real,usersys,如果可能的话!).

谢谢

jac*_*obm 7

对于基本计时,您可以使用Guava的Stopwatch(或者如果您不想使用整个Guava库,只需获取其源代码).有关更完整的基准测试解决方案,请查看同一团队的Caliper.

这两个都是基于System.nanoTime(),你应该更喜欢System.currentTimeMillis()测量经过的时间.基本原因是它System.currentTimeMillis()是一个"时钟"(试图返回壁时间),System.nanoTime()而是一个"计时器"(试图从某个任意点返回时间).

当你想要弄清楚单个事件发生的时候,你想要一个时钟,所以你可以用你的手表或墙上的时钟(或其他计算机的时钟)排队.但它不适合测量同一系统上两个事件之间的经过时间,因为计算机偶尔会调整其内部时钟对应于挂壁时间的概念.例如,如果你这样做

long timeA = System.currentTimeMillis();
doStuff();
long timeB = System.currentTimeMillis();
System.out.println("Elapsed time: " + (timeB - timeA));
Run Code Online (Sandbox Code Playgroud)

如果NTP在doStuff()执行时向后调整,则可能会得到否定结果.System.nanoTime()作为计时器而不是时钟,应该忽略该调整,从而避免这个问题.

(请注意,以上所有内容都是概念性的;不幸的是,在实现级别上,事情可能会变得混乱.但这并没有改变建议:System.nanoTime()应该是您可以在平台上获得的最佳计时器,并且System.currentMilliseconds()应该是最好的你可以得到的时钟.)