1. ホーム
  2. java

[解決済み] Javaで正しいマイクロベンチマークを書くには?

2022-03-20 11:43:50

質問

Javaで正しいマイクロベンチマークを書く(実行する)にはどうしたらよいでしょうか?

いろいろなことを考えるためのコードサンプルやコメントを探しています。

例 ベンチマークは時間/反復を測定すべきか、反復/時間を測定すべきか、またその理由は?

関連する ストップウォッチによるベンチマークは有効ですか?

どのように解決するのですか?

マイクロベンチマークの書き方のコツ Java HotSpotの制作者より :

ルール0 JVMとマイクロベンチマークに関する評判の良い論文を読んでください。良いものは ブライアン・ゲッツ、2005年 . マイクロベンチマークに過度な期待は禁物です。マイクロベンチマークは、JVMの性能特性の限られた範囲しか測定できません。

ルール1: タイミングフェーズの前に、すべての初期化およびコンパイルをトリガーするのに十分な、テストカーネルを最後まで実行するウォームアップフェーズを必ず含んでください。(ウォームアップフェーズでの繰り返しは少なくてもかまいません。経験則では、数万回の内部ループの反復が必要です)。

ルール2. 常に -XX:+PrintCompilation , -verbose:gc このように、コンパイラやJVMの他の部分がタイミングフェーズで予期しない作業をしていないことを確認することができます。

ルール2.1 タイミングフェーズとウォームアップフェーズの最初と最後にメッセージを印刷し、タイミングフェーズ中にルール2からの出力がないことを確認できるようにします。

ルール3 との違いを意識してください。 -client-server と、OSRと通常のコンパイルがあります。また -XX:+PrintCompilation フラグは、例えば、非初期エントリポイントを示すアットマークを持つOSRコンパイルを報告します。 Trouble$1::run @ 2 (41 bytes) . 最高のパフォーマンスを求めるなら、クライアントよりサーバー、OSRよりレギュラーを優先してください。

ルール4 初期化の影響に注意する。印刷はクラスをロードし、初期化するので、タイミングフェーズで初めて印刷しないようにしてください。特にクラスの読み込みをテストする場合(その場合はテストクラスのみを読み込みます)以外は、ウォームアップフェーズ(または最終報告フェーズ)以外では新しいクラスを読み込まないでください。ルール2は、このような影響に対する最初の防御線です。

ルール5 最適化解除と再コンパイルの影響に注意すること。なぜなら、コンパイラは、そのパスが全く使用されないという以前の楽観的な仮定に基づいて、コードをジャンクにして再コンパイルする可能性があるからです。ルール2は、このような効果に対する最初の防御線です。

ルール6 適切なツールを使ってコンパイラの思考を読み、コンパイラが生成するコードに驚かされることを期待する。何が速いか遅いかについて理論を立てる前に、自分でコードを検証してください。

ルール7 測定値のノイズを減らす。静かなマシンでベンチマークを実行し、異常値を除外して何度か実行します。使用方法 -Xbatch を設定して、コンパイラをアプリケーションと直列化することを検討します。 -XX:CICompilerCount=1 で、コンパイラが自分自身と並列に実行されないようにします。GCオーバーヘッドを減らすために Xmx (十分に大きい)イコール Xms を使用し UseEpsilonGC がある場合は、それを使用することができます。

ルール8 ベンチマークには、おそらくより効率的で、この目的だけのためにすでにデバッグされたライブラリを使用してください。例えば JMH , キャリパー または ビルとポールの優れたUCSDベンチマーク(Java用 .