BenchMark工具-JMH介紹

    JMH是有OpenJDK開發的基準測試(Benchmark)工具。JMH能夠爲寫基準測試和運行測試提供很好的支持。JMH在Concurrent Benchmarks也提供很好的支持,能夠說是多功能測試工具。JMH在2013被公佈出來,如今最新版本到1.9。java

    JMH基本用法:git

       JMH環境構建github

      1 使用maven工程,直接在項目中引入相應的jar包json

    

<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-core</artifactId>
    <version>${jmh.version}</version>
</dependency>
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>${jmh.version}</version>
    <scope>provided</scope>
</dependency>

   2 或者直接用JMH的archetype建立:jvm

           mvn archetype:generate \
          -DinteractiveMode=false \
          -DarchetypeGroupId=org.openjdk.jmh \
          -DarchetypeArtifactId=jmh-java-benchmark-archetype \
          -DgroupId=com.yao \
          -DartifactId=jmh-demo \
          -Dversion=1.0

  環境搭建好以後而後就能夠寫相應的測試用例了maven

  Demo以下ide

public class JMHSample_01_HelloWorld {
    @Benchmark
    public void wellHelloThere() {
        // this method was intentionally left blank.
    }
    /*
  
     * a) Via command-line:
     *    $ mvn clean install
     *    $ java -jar target/benchmarks.jar JMHSample_01
     *
     * JMH generates self-contained JARs, bundling JMH together with it.
     * The runtime options for the JMH are available with "-h":
     *    $ java -jar target/benchmarks.jar -h
     *
     * b) Via the Java API:
     *    (see the JMH homepage for possible caveats when running from IDE:
     *      http://openjdk.java.net/projects/code-tools/jmh/)
     */

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_01_HelloWorld.class.getSimpleName())
                .forks(1)
                .build();
        new Runner(opt).run();
    }

運行上面的Demo有兩種方法:一個是直接打包,而後會在target中生成benchmarks.jar,裏面帶有main方法,就直接能夠運行:java -jar target/benchmarks.jar。運行後的結果以下格式:(運行的結果也寫入指定的文件)工具

Result "wellHelloThere":

  3142305096.924 ±(99.9%) 17949665.603 ops/s [Average]
    (min, avg, max) = (2907217981.526, 3142305096.924, 3226536099.659), stdev = 76000008.112
      CI (99.9%): [3124355431.320, 3160254762.527] (assumes normal distribution)


# Run complete. Total time: 00:06:42
  Benchmark                Mode  Cnt           Score          Error  Units
  MyBenchmark.testMethod  thrpt  200  3142305096.924 ± 17949665.603  ops/s

同時也支持在IDE中直接運行。測試

每每在寫用例的時候,能夠不寫main方法,直接在方法上寫個Junit的Test註解 ,功能和main相同。ui

好比netty5中爲全部的benchmarks寫了一個基類以下:

@Warmup(iterations = AbstractMicrobenchmark.DEFAULT_WARMUP_ITERATIONS)
@Measurement(iterations = AbstractMicrobenchmark.DEFAULT_MEASURE_ITERATIONS)
@Fork(AbstractMicrobenchmark.DEFAULT_FORKS)
@State(Scope.Thread)
public class AbstractMicrobenchmark {

    protected static final int DEFAULT_WARMUP_ITERATIONS = 10;
    protected static final int DEFAULT_MEASURE_ITERATIONS = 10;
    protected static final int DEFAULT_FORKS = 2;

    public static final class HarnessExecutor extends ThreadPoolExecutor {
        public HarnessExecutor(int maxThreads, String prefix) {
            super(0, maxThreads, 1L, TimeUnit.DAYS, new SynchronousQueue<Runnable>(),
                  new DefaultThreadFactory(prefix));
            System.out.println("Using harness executor");
        }
    }

    protected static final String[] JVM_ARGS = {
        "-server", "-dsa", "-da", "-ea:io.netty...", "-Xms768m", "-Xmx768m",
        "-XX:MaxDirectMemorySize=768m", "-XX:+AggressiveOpts", "-XX:+UseBiasedLocking",
        "-XX:+UseFastAccessorMethods", "-XX:+UseStringCache", "-XX:+OptimizeStringConcat",
        "-XX:+HeapDumpOnOutOfMemoryError", "-Dio.netty.noResourceLeakDetection",
        "-Dharness.executor=CUSTOM",
        "-Dharness.executor.class=io.netty.microbench.util.AbstractMicrobenchmark$HarnessExecutor"
    };

    static {
        ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED);
    }

    @Test
    public void run() throws Exception {
        String className = getClass().getSimpleName();

        ChainedOptionsBuilder runnerOptions = new OptionsBuilder()
            .include(".*" + className + ".*")
            .jvmArgs(JVM_ARGS);

        if (getWarmupIterations() > 0) {
            runnerOptions.warmupIterations(getWarmupIterations());
        }

        if (getMeasureIterations() > 0) {
            runnerOptions.measurementIterations(getMeasureIterations());
        }

        if (getForks() > 0) {
            runnerOptions.forks(getForks());
        }

        if (getReportDir() != null) {
            String filePath = getReportDir() + className + ".json";
            File file = new File(filePath);
            if (file.exists()) {
                file.delete();
            } else {
                file.getParentFile().mkdirs();
                file.createNewFile();
            }

            runnerOptions.resultFormat(ResultFormatType.JSON);
            runnerOptions.result(filePath);
        }

        new Runner(runnerOptions.build()).run();
    }

    protected int getWarmupIterations() {
        return SystemPropertyUtil.getInt("warmupIterations", -1);
    }

    protected int getMeasureIterations() {
        return SystemPropertyUtil.getInt("measureIterations", -1);
    }

    protected int getForks() {
        return SystemPropertyUtil.getInt("forks", -1);
    }

    protected String getReportDir() {
        return SystemPropertyUtil.get("perfReportDir");
    }
}

    

    我這裏僅僅是入門性的介紹,具體的參數和用法本人也不是很熟悉。

具體介紹和用法參照:http://openjdk.java.net/projects/code-tools/jmh/

本人經過官網摘抄的例子,傳到github上了:https://github.com/WangErXiao/jmh-demo

END-----------------------------------------------------------------------------------------

轉發標註來源:http://my.oschina.net/robinyao/blog/408285

相關文章
相關標籤/搜索