baby sword‘s blog baby sword‘s blog
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)

zhengjian

不敢承担失去的风险,是不可能抓住梦想的
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)
  • 华仔聊技术

  • 业务设计

  • 场景设计

  • 运维

  • 安全

  • 面试

  • mac相关工具推荐

  • 开发工具

    • git安装后怎么做
    • git介绍
    • git常用命令
    • git三剑客
    • git标签详解
    • merge的方式
    • 记一次git rebase操作
    • 持续集成、持续交付、持续部署
    • 开机自启脚本方法
    • shell语法
    • 解决mac安装软件后显示已经被损坏
    • 不同序列化工具性能测试
    • JMH测试工具介绍
  • 人工智能

  • 推荐

  • 阅读

  • 工具

  • 计划

  • 产品

  • 云原生

  • go

  • QVM

  • 软件设计师

  • 极客时间

  • 单元测试

  • 其他
  • 开发工具
xugaoyi
2023-06-09

JMH测试工具介绍

介绍 什么是JMH

JMH和jMeter的使用场景还是有很大的不同的,jMeter更多的是对rest api进行压测,而JMH关注的粒度更细,它更多的是发现某块性能槽点代码,然后对优化方案进行基准测试对比。比如json序列化方案对比,bean copy方案对比,文中提高的洗牌算法对比等。

JMH(Java Microbenchmark Harness)是一个专门用于编写和运行 Java 微基准测试的框架。

一般使用流程如下

下面简单介绍一下如何使用 JMH 进行基准测试:

  1. 添加依赖:在项目中添加 JMH 的依赖,可以通过 Maven 或 Gradle 等构建工具配置。
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-core</artifactId>
    <version>1.33</version>
</dependency>

<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>1.33</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
  1. 编写基准测试代码:创建一个类,并在其中编写需要进行基准测试的方法。
  2. 使用 @Benchmark 注解标记需要进行基准测试的方法。
  3. 配置基准测试选项:可以使用 @State 注解来配置基准测试的状态,例如共享变量、线程数等。
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;

@State(Scope.Thread)
public class MyBenchmark {
    
    int x = 1;
    int y = 2;
    
    @Benchmark
    public int add() {
        return x + y;
    }
    
    @Benchmark
    public int subtract() {
        return x - y;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  1. 运行基准测试:可以使用命令行或者其他可视化工具来运行基准测试,例如使用 Maven 命令 mvn clean install 或 mvn clean install -DskipTests=false
  2. 分析结果:JMH 会输出详细的测试结果,包括每个测试方法的平均时间、吞吐量、方差、标准差等统计数据,可以根据这些数据来分析和比较基准测试的结果。
Benchmark              Mode  Cnt   Score   Error  Units
MyBenchmark.add       thrpt   20  16.313 ± 0.076  ops/s
MyBenchmark.subtract  thrpt   20  16.304 ± 0.076  ops/s
1
2
3

解释一下,这里是测的是吞吐量,那么score表示就是每秒执行了 16 次。后面的error表示的是误差。cnt表示迭代次数。

JMH的使用

  1. @BenchmarkMode

用来配置 Mode 选项,可用于类或者方法上,这个注解的 value 是一个数组,可以把几种 Mode 集合在一起执行,如:@BenchmarkMode({Mode.SampleTime, Mode.AverageTime}),还可以设置为 Mode.All,即全部执行一遍。

  1. Throughput:整体吞吐量,每秒执行了多少次调用,单位为 ops/time

  2. AverageTime:用的平均时间,每次操作的平均时间,单位为 time/op

  3. SampleTime:随机取样,最后输出取样结果的分布

  4. SingleShotTime:只运行一次,往往同时把 Warmup 次数设为 0,用于测试冷启动时的性能

  5. All:上面的所有模式都执行一次

  6. @State

通过 State 可以指定一个对象的作用范围,JMH 根据 scope 来进行实例化和共享操作。@State 可以被继承使用,如果父类定义了该注解,子类则无需定义。由于 JMH 允许多线程同时执行测试,不同的选项含义如下:

  1. Scope.Benchmark:所有测试线程共享一个实例,测试有状态实例在多线程共享下的性能

  2. Scope.Group:同一个线程在同一个 group 里共享实例

  3. Scope.Thread:默认的 State,每个测试线程分配一个实例

  4. @OutputTimeUnit

为统计结果的时间单位,可用于类或者方法注解

  1. @Warmup

预热所需要配置的一些基本测试参数,可用于类或者方法上。一般前几次进行程序测试的时候都会比较慢,所以要让程序进行几轮预热,保证测试的准确性。参数如下所示:

  1. iterations:预热的次数
  2. time:每次预热的时间
  3. timeUnit:时间的单位,默认秒
  4. batchSize:批处理大小,每次操作调用几次方法

为什么需要预热? 因为 JVM 的 JIT 机制的存在,如果某个函数被调用多次之后,JVM 会尝试将其编译为机器码,从而提高执行速度,所以为了让 benchmark 的结果更加接近真实情况就需要进行预热。

  1. @Measurement

实际调用方法所需要配置的一些基本测试参数,可用于类或者方法上,参数和 @Warmup 相同。

  1. @Threads

每个进程中的测试线程,可用于类或者方法上。

  1. @Fork

进行 fork 的次数,可用于类或者方法上。如果 fork 数是 2 的话,则 JMH 会 fork 出两个进程来进行测试。

  1. @Param

指定某项参数的多种情况,特别适合用来测试一个函数在不同的参数输入的情况下的性能,只能作用在字段上,使用该注解必须定义 @State 注解。

在介绍完常用的注解后,让我们来看下 JMH 有哪些陷阱。

可参考文档:

https://www.cnblogs.com/54chensongxia/p/15485421.html

编辑 (opens new window)
上次更新: 2024/02/22, 14:03:19
不同序列化工具性能测试
Claude对话ai

← 不同序列化工具性能测试 Claude对话ai→

最近更新
01
spark基础
02-22
02
mysql读写分离和分库分表
02-22
03
数据库迁移
02-22
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式