この質問では、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 コンパイルを強制するのに十分な頻度でコードを実行して測定する
- コードをループで実行し、実行時間を測定します。最小値を記憶し、この値が安定したらループを中止します。
私の理論的根拠は、通常、一部のコードの速度 (下限) を知りたいということです。外部イベント (マウスの動き、デスクトップにアナログ時計があるためグラフィックス カードからの割り込み、スワッピング、ネットワーク パケットなど) によって任意のコードが遅くなる可能性がありますが、ほとんどの場合、どれだけ速いか知りたいだけです。私のコードは完璧な状況下にある可能性があります。
また、コードを数秒または数分実行する必要がないため (不要な影響をキャンセルするため)、パフォーマンス測定がはるかに高速になります。
誰かがこれを確認/デバンクできますか?