目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

JMH基准测试

JMH 简介

 JMH,即 Java Microbenchmark Harness,这是专 ⻔ ⽤于进 ⾏代码的微基准测试的 ⼀套 ⼯具 API,JMH 由 OpenJDK/Oracle ⾥ ⾯那群开发了 Java 编译器的人员所开发。

使用场景

  • 已经找出了热点函数,⽽需要对热点函数进 ⾏进 ⼀步的优化时,就可以使 ⽤ JMH 对优化的效 果进 ⾏定量的分析。
  • 想定量地知道某个函数需要执 ⾏多 ⻓时间,以及执 ⾏时间和输 ⼊ n 的相关性
  • ⼀个函数有两种不同实现(例如 JSON 序列化/反序列化有 Jackson 和 Gson 实现),不知道哪种 实现性能更好

快速上手

引入依赖

 1<dependency>
 2            <groupId>org.openjdk.jmh</groupId>
 3            <artifactId>jmh-core</artifactId>
 4            <version>1.21</version>
 5        </dependency>
 6        <dependency>
 7            <groupId>org.openjdk.jmh</groupId>
 8            <artifactId>jmh-generator-annprocess</artifactId>
 9            <version>1.21</version>
10            <scope>provided</scope>
11        </dependency>

编写基准测试类(战 SpringBoot 整合 JMH)

 1import org.openjdk.jmh.annotations.*;
 2import org.openjdk.jmh.runner.Runner;
 3import org.openjdk.jmh.runner.RunnerException;
 4import org.openjdk.jmh.runner.options.Options;
 5import org.openjdk.jmh.runner.options.OptionsBuilder;
 6import org.springframework.boot.SpringApplication;
 7import org.springframework.context.ApplicationContext;
 8import org.springframework.context.ConfigurableApplicationContext;
 9import org.springframework.context.support.ClassPathXmlApplicationContext;
10
11
12@State(Scope.Thread)
13public class JMHSpringbootTest {
14
15
16    private ConfigurableApplicationContext context;
17    private CouponService couponService;
18
19
20    public static void main(String[] args) throws RunnerException {
21        Options options = new OptionsBuilder()
22                .include(JMHSpringbootTest.class.getName() + ".*")  //指定基准测试的方法
23                .warmupIterations(2)    //预热
24                .measurementIterations(2)   //正式计量
25                .forks(1).build();
26        new Runner(options).run();
27    }
28
29    /**
30     * setup初始化容器的时候只执行一次
31     */
32    @Setup(Level.Trial)
33    public void init(){
34        String arg = "";
35        context = SpringApplication.run(CouponAppApplication.class,arg);
36        couponService = context.getBean(CouponService.class);
37    }
38
39
40    /**
41     * benchmark执行多次,此注解代表触发我们所要进行基准测试的方法
42     */
43    @Benchmark
44    public void test(){
45        System.out.println(couponService.getCouponList());
46    }
47    
48}

测试结果

 1# Run complete. Total time: 00:01:27
 2
 3REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
 4why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
 5experiments, perform baseline and negative tests that provide experimental control, make sure
 6the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
 7Do not assume the numbers tell you what you want them to tell.
 8
 9Benchmark                Mode  Cnt    Score   Error  Units
10JMHSpringbootTest.test  thrpt    2  680.070          ops/s

作者:Soulboy