Java Microbenchmark Harness (JMH)
Use Case
- メソッドの実行 時間 と、実行 時間 と入力 の相関 関係 を正確 に把握 したい
- インターフェースの異 なる条件 での実装 のスループットを比較
- リクエストの何 パーセントがどのくらいの時間 で完了 するか確認
Annotation
@BenchmarkModeclass / methodで使用Throughout: 全体 スループット、例 えば1秒 間 に何 回 呼 び出 せるか、単位ops/timeAverageTime: 各 操作 の平均 時間 、単位time/opSampleTime: ランダムサンプリング、サンプリング結果 の分布 を出力SingleShotTime: 1回 だけ実行 、通常@Warmupの回数 を0に設定 、コールドスタートの性能 テスト用All: 上記 すべてのモードを1回 ずつ実行
@State- オブジェクトの作用
範囲
を指定
Scope.Benchmark: すべてのテストThreadが1つのinstanceを共有 、状態 を持 つinstanceのMulti-Thread共有 時 の性能 をテストScope.Group: 同 じThread、同 じgroup内 でinstanceを共有Scope.Thread: デフォルトstate、各 Test Threadに1つのinstanceを割 り当 て
- オブジェクトの作用
範囲
を指定
@OutputTimeUnit- 統計
結果
の時間
単位
、
class / methodで使用
- 統計
結果
の時間
単位
、
@Warmup- 一般
的
に最初
の数回
のテストは遅
くなるため、正確
なテストのために数回
ウォームアップが必要
iterations: ウォームアップ回数time: 各 ウォームアップ時間timeUnit: デフォルトsecondbatchSize: バッチサイズ、各 操作 で何 回 メソッドを呼 び出 すか
- 一般
的
に最初
の数回
のテストは遅
くなるため、正確
なテストのために数回
ウォームアップが必要
ウォームアップの理由 :
JVMにはJIT<ruby class="hx-furigana">機構<rp>(</rp><rt>きこう</rt><rp>)</rp></ruby> があり、func()が複数
回
呼
ばれると、JVMはMachine Codeにコンパイルして実行
速度
を向上
させようとする。benchmarkの結果
を実際
の状況
に近
づけるためにウォームアップが必要
。
@Measurement:Method呼 び出 しに必要 な基本 テストパラメータを設定 、class/methodで使用 可能 、Paramsは@Warmupと同 じ@Threads: 各Process内 のTest Thread、class/methodで使用 可能@Fork: fork number = 2の場合 、JMHは2つのProcessをforkしてテストを実行 、class/methodで使用 可能@Param:func()の異 なるパラメータ入力 時 の性能 テストに特 に適 している、フィールドにのみ適用 、このアノテーションを使用 する場合@Stateの定義 が必要
Result Analyze
Result "com.lex.StringConnectTest.testStringBuilderAdd":
426.954 ±(99.9%) 60.926 ns/op [Average]
(min, avg, max) = (409.871, 426.954, 452.426), stdev = 15.822
CI (99.9%): [366.027, 487.880] (assumes normal distribution)426.954 ±(99.9%) 60.926 ns/op [Average]- 各 操作 の平均 所要 時間 426.954 ± 60.926 ナノ秒
- 最小値
:
409.871 - 平均値
:
426.954 - 最大値
:
452.426 - 標準偏差
:
15.822 - 平均値
の信頼
区間
:
[366.027, 487.880]
Benchmark (length) Mode Cnt Score Error Units
StringConnectTest.testStringAdd 10 avgt 5 133.950 ± 3.264 ns/op
StringConnectTest.testStringAdd 50 avgt 5 1121.863 ± 55.314 ns/op
StringConnectTest.testStringAdd 100 avgt 5 3544.262 ± 199.877 ns/op
StringConnectTest.testStringBuilderAdd 10 avgt 5 46.597 ± 3.005 ns/op
StringConnectTest.testStringBuilderAdd 50 avgt 5 217.872 ± 11.888 ns/op
StringConnectTest.testStringBuilderAdd 100 avgt 5 426.954 ± 60.926 ns/oplength:@Param値Mode:@BenchmarkModeのモードCnt:@Measurement()実行 回数Score:- ベンチマークモードが
Throughputの場合 、 高 いスコアは良 い性能 を示 す(単位 時間 あたりの操作 数 を測定 するため、例 えば秒 あたりの操作 数 ) - ベンチマークモードが
AverageTimeの場合 、 低 いスコアは良 い性能 を示 す(1回 の操作 にかかる時間 を測定 するため、例 えば操作 あたりのナノ秒 )
- ベンチマークモードが
Error: 誤差 、信頼 区間Units: 各 呼 び出 しの単位 時間