用Java测量时间
因此,我试图测量两种不同算法实现完成给定任务所需的时间,结果如下:用Java测量时间,java,performance,time,profiling,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 是i只是一些输入参数 我已经使用以下(朴素)函数测量了算法的性能: private do
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
是i
只是一些输入参数
我已经使用以下(朴素)函数测量了算法的性能:
private double getDuration() {
return (double)(System.currentTimeMillis() - startTime) / (double)1000;
}
与使用System.currentTimeMillis()
相比,获得更真实结果(而不是0.0,这显然不是真的!)的更好方法是什么?我知道我可以一次又一次地运行这些算法并总结它们的结果,但我有一种直觉,在Java中可能有一种更可靠的方法来测量经过的时间(如果可能的话,real
、user
和sys
)
谢谢
System.nanoTime()代码>也许,就是你要找的。并添加标准偏差和平均时间的计算。对于基本计时,您可以使用Guava(或者如果不想获取整个Guava库,只需获取其源代码)。要获得更完整的基准测试解决方案,请查看同一团队
这两种方法都基于System.nanoTime()
,您应该更喜欢使用System.currentTimeMillis()
来测量经过的时间。基本原因是System.currentTimeMillis()
是一个“时钟”(尝试返回墙上的时间),而System.nanoTime()
是一个“计时器”(尝试从某个任意点返回时间)
当你想知道某个事件何时发生时,你需要一个时钟,这样你就可以把它与手表或墙上的时钟(或其他计算机上的时钟)对齐。但它不适合测量同一系统上两个事件之间的经过时间,因为计算机偶尔会调整其内部时钟如何与墙时间相对应的概念。例如,如果你这样做
long timeA = System.currentTimeMillis();
doStuff();
long timeB = System.currentTimeMillis();
System.out.println("Elapsed time: " + (timeB - timeA));
如果在执行doStuff()
时NTP向后调整,则可能会得到负面结果System.nanoTime()
,作为计时器而不是时钟,应该忽略该调整,从而避免此问题
(请注意,以上所有内容都是概念性的;不幸的是,在实现层面上,事情可能会变得混乱。但这并没有改变建议:System.nanoTime()
应该是您在平台上可以获得的最佳计时器,System.currentmilless()
应该是您可以获得的最佳时钟。) 你应该考虑多次运行算法并平均结果。
原因有三:
由于您已经确定的原因,它使计时变得更容易
JVM会“预热”,代码的性能也会随之改变:热点JVM在您大量运行一个方法之前不会完全编译。如果你不能克服这一点,你的结果将不具有代表性
计算时间的平均值总是一个好主意,以避免由于外部事件(如GC)或计算机上运行的其他东西而产生的虚假影响
根据经验,试着在热身时运行你的algos 10000次,然后再运行10000次。修改数字以适合您的运行时
解释同样的事情。您可以插入代码并计算执行的字节码数。你可以用它来做这件事
这可能不适合您的目的。如果程序之间只有很少几个字节码的差异,那么可能无法准确衡量哪个程序的性能更高,因为执行字节码的成本可能差异很大。此外,如果在您的程序中有网络或磁盘读取,字节码计数可能会给出错误的比较 当你测量很短的时间间隔时,你最终测量的测量逻辑比你测量的预期“目标”要多。那么运行每个alg一百万次有什么问题?随机参数?回答得好。还有一件事,当我唯一想比较两种算法时,我是不是最好在启用-Xint标志的情况下运行JVM,这样我就不必担心奇怪的JIT效果了?当然,您对比较正常操作(包括编译)下的算法性能感兴趣?在这种情况下,绝对不是-解释的运行时可能是无关的。你大概是在比较它们,因为在一些更大的应用程序中使用时,性能对你很重要?如果您不在现实环境中运行测试,那么结果本身就不现实。重要提示:对于OP所描述的基准测试,Guava团队建议使用。