103.【Java Microbenchmark Harness】(六)

简介: 103.【Java Microbenchmark Harness】

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文件拖拽到这里就可以可视化了。

相关文章
|
Java
103.【Java Microbenchmark Harness】(三)
103.【Java Microbenchmark Harness】
48 0
103.【Java Microbenchmark Harness】(三)
|
Java
103.【Java Microbenchmark Harness】(二)
103.【Java Microbenchmark Harness】
68 0
103.【Java Microbenchmark Harness】(二)
|
Java
103.【Java Microbenchmark Harness】(五)
103.【Java Microbenchmark Harness】
121 0
|
Java 编译器 BI
103.【Java Microbenchmark Harness】(四)
103.【Java Microbenchmark Harness】
76 0
|
Java 测试技术
103.【Java Microbenchmark Harness】(一)
103.【Java Microbenchmark Harness】
69 0
|
Java 测试技术
在java中使用JMH(Java Microbenchmark Harness)做性能测试
在java中使用JMH(Java Microbenchmark Harness)做性能测试
|
12天前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
91 38
|
9天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
4天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####
|
5天前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
23 4