使用JMH工具进行性能测试

介绍

JMH,即Java Microbenchmark Harness,从名字就可以看出,这是专门用于进行代码的微基准测试的一套工具API。它为我们进行微基准测试提供了一系列的方法,帮助使用者屏蔽在微基准测试中容易产生的随机性误差。

开始使用

因为这一套工具API尚未加入到标准的JavaAPI中,因此,在使用的时候需要另外依赖一些jar包。同时考虑到,微基准测试一般是用于应用程序的发布或者一些性能相关的代码变更,在正常的工程中,往往不需要长期依赖这些测试代码,因此,在正式的文档中,也建议使用者,以独立的微基准测试工程的形式使用,需要测试的代码,通过jar依赖的方式添加到微基准测试的工程中。

使用Maven创建微基准测试工程

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

通过官方提供的Maven archetype就可以创建出标准的JMH微测试工程,创建之后,会默认创建一个微测试的类MyBenchmark:

public class MyBenchmark {   
    @Benchmark   
    public void testMethod() {       
        // This is a demo/sample template for building your JMH benchmarks. Edit as needed.       
        // Put your benchmark code here   
    }
}

在官方提供的文档中,JMH的运行都是通过CLI进行的,但往往我们实际进行开发的时候都是使用IDE进行的,再最后会再简单介绍一下使用Intellij IDEA运行的方法。

使用JMH进行gs-collections测试

gs-collections是高盛开源出来的一个,它的具体介绍可以看看引用部分的链接。这里主要是用gs-collections作为例子来了解一下JMH的一些基本使用。

测试用例:gs-collections stream VS Java 8 stream

这个测试用例主要就是统计一下一个List中有多少个偶数:

@BenchmarkMode(Mode.Throughput)
public class CountTest {

    @Benchmark
    @Warmup(iterations = 2)
    @Measurement(iterations = 2)
    public void serialLazyJDK() {
        long evens = integersJDK.stream().filter(each -> each % 2 == 0).count();
        Assert.assertEquals(SIZE / 2, evens);
    }

    @Benchmark
    @Warmup(iterations = 2)
    @Measurement(iterations = 2)
    public void serialLazyGSC() {
        long evens = integersGSC.count(each -> each % 2 == 0);
        Assert.assertEquals(SIZE / 2, evens);
    }

    private static final int SIZE = 1_000_000;
    public final List integersJDK = new ArrayList<>(Interval.oneTo(SIZE));
    public final FastList integersGSC = new FastList<>(Interval.oneTo(SIZE));
}

首先,这里的每一个方法就跟一般的JUnit方法类似,每一个方法就是一个测试用例。那么因为我们现在是在做Benchmark,因此,最终的结果就是每一个被加上@Benchmark注解的方法的比较结果。所以,@Benchmark注解是用来标注待测试方法的。
留意到在类上有@BenchmarkMode的注解,里面的参数,Mode.Throughput,表示这个Benchmark主要是测试吞吐量的对比。在JMH中,还另外提供了测试平均运行时间等模式的测试方式。
一开始也提到,JMH就是为了解决一般的微基准测试中,容易受其他因素影响所造成的误差,因此,JMH提供了Warmup的机制,以及多次循环的测试方式。

使用IDEA运行微基准测试

跟JUnit等测试框架类似,在IDE中运行JMH测试需要额外的插件支持。在IDEA中,我们只需要在Plugins的列表中,搜索一下JMH关键字,就能找到JMH Plugin,然后安装下来,重启一下IDEA,就能运行JMH微测试。

Reference

  • OpenJDK Code Tools: JMH](http://openjdk.java.net/projects/code-tools/jmh/))
  • GS Collections

你可能感兴趣的:(使用JMH工具进行性能测试)