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】
53 0
103.【Java Microbenchmark Harness】(三)
|
Java
103.【Java Microbenchmark Harness】(二)
103.【Java Microbenchmark Harness】
72 0
103.【Java Microbenchmark Harness】(二)
|
Java
103.【Java Microbenchmark Harness】(五)
103.【Java Microbenchmark Harness】
131 0
|
Java 编译器 BI
103.【Java Microbenchmark Harness】(四)
103.【Java Microbenchmark Harness】
80 0
|
Java 测试技术
103.【Java Microbenchmark Harness】(一)
103.【Java Microbenchmark Harness】
75 0
|
Java 测试技术
在java中使用JMH(Java Microbenchmark Harness)做性能测试
在java中使用JMH(Java Microbenchmark Harness)做性能测试
|
1天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
1天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
2天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
12 3
|
2天前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
13 2