JMH Gradle Plugin

repository·master·Indexed 20 days ago

https://github.com/melix/jmh-gradle-plugin

A Gradle plugin that integrates the Java Microbenchmark Harness (JMH) into the Gradle build system. It allows developers to define, compile, and run microbenchmarks using a dedicated source set (src/jmh), providing tasks for the benchmarking lifecycle and a configuration block to map JMH command line options to Gradle properties.

Tokens
1.4K
Snippets
7
Records
8
Agent score
23%

What's inside jmh-gradle-plugin

  1. Pass JMH options at invocation time using --jmhArgs

    master

    For one-off runs where you want to change parameters (like thread count or iterations) without modifying your build.gradle, use the --jmhArgs flag. This flag is tokenized on whitespace and passed directly to the JMH runner.

    Precedence: --jmhArgs takes precedence over options defined in the jmh { ... } block.

    Warning: Because --jmhArgs is split on whitespace, it cannot correctly handle options where the value contains spaces (e.g., -p "a=1 b=2"). For such cases, use the jmhOptions property in the build.gradle file instead.

    ./gradlew jmh --jmhArgs="-t 4 -wi 5 -i 10"
  2. Install the JMH Gradle Plugin

    master

    To integrate the JMH micro-benchmarking framework with Gradle, add the me.champeau.jmh plugin to your build.gradle file.

    Note: Versions prior to 0.6.0 used the plugin ID me.champeau.gradle.jmh. Use the current ID for newer versions.

    Compatibility: Version 0.6+ requires Gradle 6.8 or higher.

    plugins {
      id "me.champeau.jmh" version "0.7.3"
    }
  3. Configure benchmark source directories and dependencies

    master

    The plugin expects benchmark source files to be located in the src/jmh directory to avoid polluting your production source sets.

    Structure:

    • src/jmh/java: Java sources for benchmarks
    • src/jmh/resources: Resources for benchmarks

    To add dependencies specifically for your benchmarks (e.g., a library used only within benchmark code), use the jmh configuration. You can also manage the JMH version itself by declaring the specific JMH artifacts in the dependencies block.

    // Adding a benchmark-only dependency
    dependencies {
        jmh 'commons-io:commons-io:2.7'
    }
    
    // Upgrading the JMH version used by the plugin
    dependencies {
        jmh 'org.openjdk.jmh:jmh-core:0.9'
        jmh 'org.openjdk.jmh:jmh-generator-annprocess:0.9'
        jmh 'org.openjdk.jmh:jmh-generator-bytecode:0.9'
    }
  4. Configure JMH execution options

    master

    You can customize benchmark execution using the jmh { ... } configuration block in build.gradle. Most options fall back to default JMH values if left unset.

    Commonly used options include:

    • includes / excludes: Regular expressions to filter benchmarks.
    • iterations: Number of measurement iterations.
    • benchmarkMode: e.g., ['thrpt', 'ss'] (Throughput, SingleShot).
    • fork: Number of times to fork the JVM.
    • threads: Number of worker threads.
    • resultFormat: Output format (CSV, JSON, NONE, SCSV, TEXT).
    • includeTests: Set to true to include test sources in the generated JMH jar.
    jmh {
       includes = ['some regular expression']
       iterations = 10
       benchmarkMode = ['thrpt', 'ss']
       fork = 2
       resultFormat = 'CSV'
       includeTests = true
    }
  5. Handle duplicate classes in JMH fat jars

    master

    When creating the JMH fat jar (jmhJar task), the plugin merges dependencies from jmh, runtime, and optionally testRuntime.

    By default, the plugin uses DuplicatesStrategy.FAIL via the duplicateClassesStrategy property. If your project contains duplicate classes, the build will fail. You can change this to DuplicatesStrategy.WARN or other strategies within the jmh block.

    To handle non-class duplicate files, it is recommended to use the Shadow Plugin.

    jmh {
      duplicateClassesStrategy = DuplicatesStrategy.WARN
    }
  6. Map JMH command line options to Gradle properties

    master

    The following table maps standard JMH command line flags to the plugin's jmh extension properties:

    JMH OptionExtension Property
    -bm <mode>benchmarkMode
    -bs <int>batchSize
    -e <regexp+>exclude
    -f <int>fork
    -i <int>iterations
    -jvm <string>jvm
    -o <filename>humanOutputFile
    -p <param>benchmarkParameters
    -prof <profiler>profilers
    -rf <type>resultFormat
    -t <int>threads
    -v <mode>verbosity
    -w <time>warmup
    -wi <int>warmupIterations
    (raw options)jmhOptions
  7. Run JMH benchmarks via Gradle tasks

    master

    The plugin provides several tasks for the benchmarking lifecycle. The jmh task is the primary entry point as it depends on the others.

    • jmh: Executes the benchmarks (main task).
    • jmhClasses: Compiles raw benchmark code.
    • jmhRunBytecodeGenerator: Runs the bytecode generator over raw code.
    • jmhCompileGeneratedClasses: Compiles the generated benchmarks.
    • jmhJar: Builds the JMH jar containing the runtime and compiled benchmark classes.
    gradle jmh