15. @Group和@GroupThreads (组数和线程)
可以更加的接近生产环境
源码
@Group("g") // 假如这个注解里面的字符串相同,那就说明它们是一组
@GroupThreads(3) // 这个地方会创建三个线程进行执行
package org.openjdk.jmh.samples; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @State(Scope.Group) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Warmup(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS) //预热次数和时间 @Measurement(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS) //测试次数和时间 public class JMHSample_15_Asymmetric { private AtomicInteger counter; @Setup //基准初始化前 public void up() { counter = new AtomicInteger(0); } @Benchmark @Group("g") // 假如这个注解里面的字符串相同,那就说明它们是一组 @GroupThreads(1) // 这个地方会创建三个线程进行执行 public int inc() { return counter.incrementAndGet(); //自增的操作 } @Benchmark @Group("g") // 假如这个注解里面的字符串相同,那就说明它们是一组 @GroupThreads(1) // 这个地方会创建三个线程进行执行 public int get() { return counter.get(); //获取值的操作 } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(JMHSample_15_Asymmetric.class.getSimpleName()) .forks(1) .build(); new Runner(opt).run(); } }
总的
Benchmark Mode Cnt Score Error Units
JMHSample_15_Asymmetric.g avgt 56.784 ns/op
JMHSample_15_Asymmetric.g:get avgt 26.845 ns/op
JMHSample_15_Asymmetric.g:inc avgt 66.764 ns/op
单独执行 get
Benchmark Mode Cnt Score Error Units
JMHSample_15_Asymmetric.g avgt 1.986 ns/op
单独执行inc 3个线程
Benchmark Mode Cnt Score Error Units JMHSample_15_Asymmetric.g avgt 40.330 ns/op
单独执行inc 1个线程
Benchmark Mode Cnt Score Error Units
JMHSample_15_Asymmetric.g avgt 6.659 ns/op
(四)、JMH实战
1.导入三个依赖
<dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-core</artifactId> <version>1.23</version> </dependency> <dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>1.23</version> </dependency> <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.5</version> </dependency>
2.比较冒泡排序和快速排序
package com.example.springboot01hello; import org.junit.jupiter.api.Test; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; import org.springframework.boot.test.context.SpringBootTest; import java.util.Arrays; import java.util.concurrent.TimeUnit; @SpringBootTest @State(Scope.Thread) @Warmup(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS) //预热次数和时间 @Measurement(iterations = 1,time = 1,timeUnit = TimeUnit.SECONDS) //测试次数和时间 public class SpringBoot01HelloApplicationTests { int array[]={1,2,5,3,6,9}; @Benchmark public void wellHelloThere1() throws Exception { sort(array); } @Benchmark public void wellHelloThere2() throws Exception { sort(array); } public int[] sort(int[] sourceArray) throws Exception { // 对 arr 进行拷贝,不改变参数内容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); for (int i = 1; i < arr.length; i++) { // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。 boolean flag = true; for (int j = 0; j < arr.length - i; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; flag = false; } } if (flag) { break; } } return arr; } public int[] sort1(int[] sourceArray) throws Exception { // 对 arr 进行拷贝,不改变参数内容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的 for (int i = 1; i < arr.length; i++) { // 记录要插入的数据 int tmp = arr[i]; // 从已经排序的序列最右边的开始比较,找到比其小的数 int j = i; while (j > 0 && tmp < arr[j - 1]) { arr[j] = arr[j - 1]; j--; } // 存在比其小的数,插入 if (j != i) { arr[j] = tmp; } } return arr; } @Test void contextLoads() throws RunnerException { Options opt = new OptionsBuilder() .include(SpringBoot01HelloApplicationTests.class.getSimpleName()) .forks(1) .build(); new Runner(opt).run(); } }
3.报表可视化
配置
Options opt = new OptionsBuilder() .include(SpringBoot01HelloApplicationTests.class.getSimpleName()) .forks(1) .resultFormat(ResultFormatType.JSON) //报表需要一个JSON文件 .result("/E:/加速器/result.json") //报表存放的位置 .build(); new Runner(opt).run();
可视化工具链接: https://jmh.morethan.io/
把生成的json文件拖拽到这里就可以可视化了。