0Pricing
Java Academy · レッスン

ベンチマークの記述

@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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. JMH を使う理由
  2. ベンチマークの記述
  3. ウォームアップと反復
  4. デッドコード削除の回避
← Java Academyに戻る