使用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<Integer> integersJDK = new ArrayList<>(Interval.oneTo(SIZE));
    public final FastList<Integer> 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 5,160评论 0 5
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,950评论 25 709
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,301评论 19 139
  • 我只是在此处重述一个在我的梦境中真实发生的故事。 时间,黄梅时节。地点,一个拍摄古装的电影城。人物,一个男人和...
    不耕田的牛阅读 1,898评论 0 0
  • 一、OC基本语法 //整型 NSInteger a = 10; //浮点型 CGFloat b = 2.3; //...
    GOT_HODOR阅读 2,405评论 0 0