Java Microbenchmark Harness (JMH)

Use Case

  • メソッドの実行(じっこう) 時間(じかん) と、実行(じっこう) 時間(じかん)入力(にゅうりょく)相関(そうかん) 関係(かんけい)正確(せいかく)把握(はあく) したい
  • インターフェースの(こと) なる条件(じょうけん) での実装(じっそう) のスループットを比較(ひかく)
  • リクエストの(なん) パーセントがどのくらいの時間(じかん)完了(かんりょう) するか確認(かくにん)

Annotation

  • @BenchmarkMode
    • class / method使用(しよう)
      • Throughout: 全体(ぜんたい) スループット、(れい) えば 1(びょう) (かん)(なん) (かい) ()() せるか単位(たんい) ops/time
      • AverageTime: (かく) 操作(そうさ)平均(へいきん) 時間(じかん)単位(たんい) time/op
      • SampleTime: ランダムサンプリング、サンプリング結果(けっか)分布(ぶんぷ)出力(しゅつりょく)
      • SingleShotTime: 1(かい) だけ実行(じっこう)通常(つうじょう) @Warmup回数(かいすう)0設定(せってい) 、コールドスタートの性能(せいのう) テスト(よう)
      • All: 上記(じょうき) すべてのモードを1(かい) ずつ実行(じっこう)
  • @State
    • オブジェクトの作用(さよう) 範囲(はんい)指定(してい)
      • Scope.Benchmark: すべてのテストThreadが1つのinstance共有(きょうゆう)状態(じょうたい)() つinstanceMulti-Thread共有(きょうゆう) ()性能(せいのう) をテスト
      • Scope.Group: (おな) じThread、(おな) じgroup(ない) でinstanceを共有(きょうゆう)
      • Scope.Thread: デフォルトstate、(かく) Test Threadに1つのinstanceを()()
  • @OutputTimeUnit
    • 統計(とうけい) 結果(けっか)時間(じかん) 単位(たんい)class / method使用(しよう)
  • @Warmup
    • 一般(いっぱん) (てき)最初(さいしょ)数回(すうかい) のテストは(おそ) くなるため、正確(せいかく) なテストのために数回(すうかい) ウォームアップが必要(ひつよう)
      • iterations: ウォームアップ回数(かいすう)
      • time: (かく) ウォームアップ時間(じかん)
      • timeUnit: デフォルトsecond
      • batchSize: バッチサイズ、(かく) 操作(そうさ)(なん) (かい) メソッドを()() すか

ウォームアップの理由(りゆう)

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 Threadclass/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/op
  • length: @Param(あたい)
  • Mode: @BenchmarkModeのモード
  • Cnt: @Measurement()実行(じっこう) 回数(かいすう)
  • Score:
    • ベンチマークモードがThroughput場合(ばあい)(たか) いスコアは()性能(せいのう)(しめ) す(単位(たんい) 時間(じかん) あたりの操作(そうさ) (すう)測定(そくてい) するため、(たと) えば(びょう) あたりの操作(そうさ) (すう)
    • ベンチマークモードがAverageTime場合(ばあい)(ひく) いスコアは()性能(せいのう)(しめ) す(1(かい)操作(そうさ) にかかる時間(じかん)測定(そくてい) するため、(たと) えば操作(そうさ) あたりのナノ(びょう)
  • Error: 誤差(ごさ)信頼(しんらい) 区間(くかん)
  • Units: (かく) ()() しの単位(たんい) 時間(じかん)