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】
122 0
|
Java 编译器 BI
103.【Java Microbenchmark Harness】(四)
103.【Java Microbenchmark Harness】
76 0
|
Java 测试技术
103.【Java Microbenchmark Harness】(一)
103.【Java Microbenchmark Harness】
71 0
|
Java 测试技术
在java中使用JMH(Java Microbenchmark Harness)做性能测试
在java中使用JMH(Java Microbenchmark Harness)做性能测试
|
8天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
|
17天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
4天前
|
安全 Java 开发者
深入解读JAVA多线程:wait()、notify()、notifyAll()的奥秘
在Java多线程编程中,`wait()`、`notify()`和`notifyAll()`方法是实现线程间通信和同步的关键机制。这些方法定义在`java.lang.Object`类中,每个Java对象都可以作为线程间通信的媒介。本文将详细解析这三个方法的使用方法和最佳实践,帮助开发者更高效地进行多线程编程。 示例代码展示了如何在同步方法中使用这些方法,确保线程安全和高效的通信。
23 9
|
7天前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####