ベンチマークの記述
@Benchmark とモードです。
「ベンチマークの記述」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
ベンチマークの作成
JMH ベンチマークは、通常のクラス内にある @Benchmark でアノテーションされたメソッドにすぎません。JMH のアノテーションプロセッサが、そのメソッドを囲むハーネスを生成します。このレッスンでは、何をどのように測定するかを定義するアノテーションについて説明します。
@Benchmark アノテーション
任意の public メソッドに @Benchmark を付けると、JMH はそのメソッドを繰り返し呼び出し、各呼び出しの時間を計測します。JMH が消費できるように、メソッドの戻り値は破棄せずに返してください。
最小限のベンチマーククラス
ベンチマークの基本形は次のとおりです。インポートするのは org.openjdk.jmh.annotations.* です。この実行環境のクラスパスには JMH が含まれていないため、これは説明用の例です。
import org.openjdk.jmh.annotations.Benchmark;
public class StringBench {
@Benchmark
public String concat() {
return "foo" + System.nanoTime();
}
}ベンチマークモード
@BenchmarkMode は、何を報告するかを選択します。
- Throughput — 単位時間あたりの処理数(大きいほど良い値です)。
- AverageTime — 1 回の処理にかかる時間(小さいほど良い値です)。
- SampleTime — 処理時間の分布(パーセンタイル)。
- SingleShotTime — 1 回の呼び出し。コールドスタートの測定に適しています。
import org.openjdk.jmh.annotations.*;
public class Bench {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
public int work() {
return 2 + 2;
}
}出力単位の選択
@OutputTimeUnit は、数値を読みやすくするためにレポートの時間単位を設定します。高速な処理にはナノ秒、低速な処理にはミリ秒が適しています。
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;
public class Bench {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public int work() {
return 42;
}
}結果の返却
処理の結果は必ず返してください。JMH は返された値を自動的に Blackhole に渡すため、デッドコード除去を防げます。計算した結果を破棄する void ベンチマークは、典型的な誤りです。
アノテーションのデフォルト
アノテーションはメソッドまたはクラス全体に付けられます。クラスレベルのアノテーションは、そのクラス内のすべての @Benchmark に適用されるため、関連するベンチマークが複数ある場合も設定を DRY に保てます。
フォーク
@Fork(n) は、ベンチマークを n 個の新しい JVM プロセスで実行します。フォークによって、以前のベンチマークで蓄積された JIT プロファイルから各実行を分離できるため、再現性が向上します。デフォルトは 1 フォークです。
import org.openjdk.jmh.annotations.*;
@Fork(2)
public class Bench {
@Benchmark
public long now() {
return System.nanoTime();
}
}Runner の起動
Options オブジェクトと Runner を設定する main からベンチマークを開始するか、生成された実行可能 JAR から開始します。include(...) の正規表現で、実行するベンチマークを選択します。
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.*;
public class Launcher {
public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include("Bench")
.build();
new Runner(opt).run();
}
}出力の読み方
JMH は、ベンチマーク名、モード、サンプル数、スコア、スコアの誤差、単位を含む表を出力します。たとえば、Bench.work avgt 25 3.142 +/- 0.011 ns/op のようになります。+/- は信頼区間を表します。
ベンチマークを絞り込む
各ベンチマークでは、1 つのことだけを測定してください。セットアップ、I/O、テスト対象の処理を混在させると、結果が不明瞭になります。準備処理は @Setup メソッドに移し(state とともに説明します)、ホットパスだけを計測するようにしてください。
クイックチェック
ベンチマークの作成方法についての理解度を確認しましょう。
まとめ
JMH ベンチマークの作成方法を学びました。
- メソッドに@Benchmarkを付け、結果を返します。
- @BenchmarkMode で Throughput、AverageTime、SampleTime、SingleShotTime のいずれかを選択します。
- @OutputTimeUnit で読みやすい単位を設定し、@Fork で新しい JVM 上の実行に分離します。
- Runner と Options、または生成された JAR から起動します。
- 各ベンチマークは、1 つのホットパスに集中させます。
よくある質問
「ベンチマークの記述」レッスンは無料ですか?
はい。「ベンチマークの記述」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「ベンチマークの記述」で何を学びますか?
@Benchmark とモードです。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「ベンチマークの記述」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- JMH を使う理由
- ベンチマークの記述
- ウォームアップと反復
- デッドコード削除の回避