在这个问题中,我想质疑如何测试 Java 代码性能的知识。通常的方法遵循以下原则:
long start = System.nanoTime();
for( int i=0; i<SOME_VERY_LARGE_NUMBER; i++) {
...do something...
}
long duration = System.nanoTime() - start;
System.out.println( "Performance: "
+ new BigDecimal( duration ).divide(
new BigDecimal( SOME_VERY_LARGE_NUMBER, 3, RoundingMode.HALF_UP ) ) );
“优化”版本将调用移动System.nanoTime()
到循环中,增加了误差范围,因为与比较相比System.nanoTime()
需要更长的时间(并且在运行时行为中更难以预测)i ++
。
我的批评是:
这给了我平均运行时间,但这个值取决于一个我并不真正感兴趣的因素:比如测试循环运行时的系统负载或 JIT/GC 启动时的跳转。
在大多数情况下,这种方法不是更好吗?
- 经常运行代码来测量以强制进行 JIT 编译
- 在循环中运行代码并测量执行时间。记住最小值并在该值稳定时中止循环。
我的理由是我通常想知道某些代码的速度有多快(下限)。任何代码都可能因外部事件(鼠标移动、显卡中断,因为桌面上有模拟时钟、交换、网络数据包……)而变得任意慢,但大多数时候,我只想知道有多快我的代码可以在完美的情况下。
它还可以使性能测量更快,因为我不必运行代码几秒钟或几分钟(以消除不需要的影响)。
有人可以确认/揭穿这一点吗?