Java:使用JMH做Benchmark基准测试

BenchMark 又叫做基准测试,主要用来测试一些方法的性能,可以根据不同的参数以不同的单位进行计算(例如可以使用吞吐量为单位,也可以使用平均时间作为单位,在 BenchmarkMode 里面进行调整)。

依赖

xml 复制代码
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-core</artifactId>
    <version>1.19</version>
</dependency>
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>1.19</version>
    <scope>provided</scope>
</dependency>

使用示例

ArrayList 和 LinkedList 的遍历的性能差别

java 复制代码
package com.demo;


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.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;


@BenchmarkMode(Mode.Throughput) // 吞吐量
@OutputTimeUnit(TimeUnit.MILLISECONDS) // 结果所使用的时间单位
@State(Scope.Thread) // 每个测试线程分配一个实例
@Fork(2) // Fork进行的数目
@Warmup(iterations = 4) // 先预热4轮
@Measurement(iterations = 10) // 进行10轮测试
public class BenchMarkDemo {

    @Param({"10", "40", "70", "100"}) // 定义四个参数,之后会分别对这四个参数进行测试
    private int n;

    private List<Integer> array;
    private List<Integer> list;

    @Setup(Level.Trial) // 初始化方法,在全部Benchmark运行之前进行
    public void init() {
        array = new ArrayList<>(0);
        list = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            array.add(i);
            list.add(i);
        }
    }

    @Benchmark
    public void arrayTraverse() {
        for (int i = 0; i < n; i++) {
            array.get(i);
        }
    }

    @Benchmark
    public void listTraverse() {
        for (int i = 0; i < n; i++) {
            list.get(i);
        }
    }

    @TearDown(Level.Trial) // 结束方法,在全部Benchmark运行之后进行
    public void arrayRemove() {
        for (int i = 0; i < n; i++) {
            array.remove(0);
            list.remove(0);
        }
    }

    public static void main(String[] args) throws RunnerException {
        Options options = new OptionsBuilder().include(BenchMarkDemo.class.getSimpleName()).build();
        new Runner(options).run();
    }
}
复制代码
# Run complete. Total time: 00:03:56

Benchmark                    (n)   Mode  Cnt       Score       Error   Units
BenchMarkDemo.arrayTraverse   10  thrpt   20  337852.300 ± 10230.514  ops/ms
BenchMarkDemo.arrayTraverse   40  thrpt   20  342619.598 ±  6272.177  ops/ms
BenchMarkDemo.arrayTraverse   70  thrpt   20  342534.411 ±  6018.479  ops/ms
BenchMarkDemo.arrayTraverse  100  thrpt   20  333470.068 ± 17285.845  ops/ms
BenchMarkDemo.listTraverse    10  thrpt   20   45899.695 ±  2960.264  ops/ms
BenchMarkDemo.listTraverse    40  thrpt   20    6615.649 ±   201.404  ops/ms
BenchMarkDemo.listTraverse    70  thrpt   20    1910.175 ±    31.484  ops/ms
BenchMarkDemo.listTraverse   100  thrpt   20     787.424 ±    25.747  ops/ms

可以结合 Score 和 Unit 这两列,看到方法的效率。这里显然 arrayTraverse 的效率比 listTraverse 的高很多,因为 Unit 单位是 ops/ms,即单位时间内执行的操作数。所以显然在遍历的时候,ArrayList的效率是比LinkedList高的。

参考
使用JMH做Benchmark基准测试

相关推荐
蒸蒸yyyyzwd2 小时前
cpp对象模型学习笔记1.1-2.8
java·笔记·学习
睡美人的小仙女1273 小时前
Threejs加载环境贴图报错Bad File Format: bad initial token
开发语言·javascript·redis
碎梦归途3 小时前
思科网络设备配置命令大全,涵盖从交换机到路由器的核心配置命令
linux·运维·服务器·网络·网络协议·路由器·交换机
程序员徐师兄3 小时前
Windows JDK11 下载安装教程,适合新手
java·windows·jdk11 下载安装·jdk11 下载教程
rayufo3 小时前
【工具】列出指定文件夹下所有的目录和文件
开发语言·前端·python
RANCE_atttackkk4 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
小天源4 小时前
nginx在centos7上热升级步骤
linux·服务器·nginx
缺点内向4 小时前
C#编程实战:如何为Word文档添加背景色或背景图片
开发语言·c#·自动化·word·.net
五岳4 小时前
DTS按业务场景批量迁移阿里云MySQL表实战(下):迁移管理平台设计与实现
java·应用·dts
AZ996ZA4 小时前
自学linux第十八天:【Linux运维实战】系统性能优化与安全加固精要
linux·运维·安全·性能优化