首页 > 编程语言 >java中的基准测试框架JMH

java中的基准测试框架JMH

时间:2024-04-08 18:23:18浏览次数:23  
标签:MyBenchmark 10 java ops list 基准 Benchmark JMH thrpt

JHM是openJDK开发的一个benchmark框架。它是一个Maven依赖,所以创建一个Maven项目,引入下面两个依赖:

    <dependency>
      <groupId>org.openjdk.jmh</groupId>
      <artifactId>jmh-core</artifactId>
      <version>1.37</version>
    </dependency>
    <dependency>
      <groupId>org.openjdk.jmh</groupId>
      <artifactId>jmh-generator-annprocess</artifactId>
      <version>1.37</version>
    </dependency>

两个依赖版本一样,版本号你可以去中心仓库查一下最新的,目前是1.37

然后就可以写一个测试类,比如我想对比一下ArrayListLinkedList哪个性能好:

你猜哪个性能好?你可能会说给中间插入值链表更快,但是怎么知道插入到哪里呢...

基准配置

我的测试类叫MyBenchmark,在main方法中配置如下:

    public static void main(String[] args) throws RunnerException {
        System.out.println("Hello World!");
        Options options = new OptionsBuilder()
                .include(MyBenchmark.class.getSimpleName())
				// 这里需要include测试类进来,使用simpleName就行
                .forks(1)
				// forks是启动几个JVM实例,每个实例单独测试,配置1就行
                .timeout(TimeValue.seconds(10))
				// timeout指定下面配置的每一次测试的超时时间,你可以改大一些
                .threads(1)
				// 线程数是同时用几个线程跑测试代码,比如我的笔记本是6核12线程的,3线程反而最好
                .warmupIterations(1)
				// 正式测试前跑几次热身。和正式测试流程一样,只是数据不计入统计结果
                .warmupTime(TimeValue.seconds(10))
				// 预热多久
                .measurementTime(TimeValue.seconds(2))
				// 正式测试每次多久
                .measurementIterations(5)
				// 测试几轮
                .build();

        new Runner(options).run();
    }

Round One

第一轮测试代码如下:


public class MyBenchmark {
    private static final int limit = 10_0000;
    @Benchmark
    public void testArrayList() {
        List<Integer> list = new ArrayList<>(1);
        for (int i = 0; i < limit; i++) {
            list.add(i);
        }
        if (false) {
            System.out.println("more");
        }
    }

    @Benchmark
    public void testLinkedList() {
        List<Integer> list = new LinkedList<>();
        for (int i = 0; i < limit; i++) {
            list.add(i);
        }
        if (false) {
            System.out.println("more");
        }
    }
}

给每个集合中加入10万个数,看每秒能执行多少次。你先猜一下结果。

执行main方法,会打印出配置信息,比如

# JMH version: 1.37
# VM version: JDK 21.0.1, Java HotSpot(TM) 64-Bit Server VM, 21.0.1+12-jvmci-23.1-b19
# VM invoker: /.sdkman/candidates/java/21.0.1-graal/bin/java
# VM options: -XX:ThreadPriorityPolicy=1 -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCIProduct -XX:-UnlockExperimentalVMOptions -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=53238:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8
# Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable)
# Warmup: 1 iterations, 10 s each
# Measurement: 5 iterations, 2 s each
# Timeout: 10 s per iteration, ***WARNING: The timeout might be too low!***
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time

测试结果:

Benchmark                    Mode  Cnt     Score      Error  Units
MyBenchmark.testArrayList   thrpt    5  1286.969 ± 1686.876  ops/s
MyBenchmark.testLinkedList  thrpt    5  1909.538 ±  373.143  ops/s

数组每秒1000多次(每次插入10万数据),链表每秒快2000次了。链表取胜!

如果数据改成1000个,结果是

Benchmark                    Mode  Cnt       Score       Error  Units
MyBenchmark.testArrayList   thrpt    5  174194.500 ± 19431.634  ops/s
MyBenchmark.testLinkedList  thrpt    5  169880.651 ± 74638.041  ops/s

数组险胜。

Round Two

这次把其中的操作改成排序,每插入一个数就进行一个倒序排序:

            list.add(i);
            list.sort(Comparator.reverseOrder());// 使用逆序,让他一定要移动数据

你猜结果如何?

先看1万个数据(10万的话我电脑可能完不成):

Benchmark                    Mode  Cnt  Score   Error  Units
MyBenchmark.testArrayList   thrpt    5  4.867 ± 2.272  ops/s
MyBenchmark.testLinkedList  thrpt    5  0.638 ± 1.323  ops/s

数组完胜!

再看100个数据:

Benchmark                    Mode  Cnt      Score       Error  Units
MyBenchmark.testArrayList   thrpt    5  79449.678 ± 97210.639  ops/s
MyBenchmark.testLinkedList  thrpt    5  32889.346 ±  2018.265  ops/s

数组还是比链表优势大很多。

Round Three

这次往中间插入值:

            list.add(i/2, 1);
//            list.sort(Comparator.reverseOrder());

看10万数据的结果就行了,你猜结果啥样:

Benchmark                    Mode  Cnt  Score   Error  Units
MyBenchmark.testArrayList   thrpt    3  3.606 ± 2.153  ops/s
MyBenchmark.testLinkedList  thrpt    3  0.151 ± 0.112  ops/s

不说了,我要去删掉我之前代码中的链表了。

标签:MyBenchmark,10,java,ops,list,基准,Benchmark,JMH,thrpt
From: https://www.cnblogs.com/somefuture/p/18122096

相关文章

  • Java实现Fast DFS、服务器、OSS上传
    支持FastDFS、服务器、OSS等上传方式介绍在实际的业务中,可以根据客户的需求设置不同的文件上传需求,支持普通服务器上传+分布式上传(FastDFS)+云服务上传OSS(OSS)软件架构为了方便演示使用,本项目使用的是前后端不分离的架构前端:Jquery.uploadFile后端:SpringBoot前期准备:F......
  • JavaScript学习 BOM操作
    BrowserObjectModel(BOM) 是一套专为与浏览器交互而设计的API,它允许JavaScript访问和操纵浏览器窗口以及浏览器本身的相关特性。以下是对BOM主要对象及其操作的详细讲解:1.Window对象Window对象 是BOM的核心,它代表浏览器窗口,并且是JavaScript全局对象。这意味着所有全局......
  • 云原生周刊:2024 年 K8s 基准报告 | 2024.4.8
    开源项目推荐ArgoCDImageUpdaterArgoCDImageUpdater是一个自动更新ArgoCD管理的Kubernetes工作负载容器镜像的工具。简而言之,它将跟踪ArgoCD应用程序资源上的注释指定的图像版本,并通过使用ArgoCDAPI设置参数覆盖来更新它们。目前,它仅适用于使用Kustomize......
  • JAVA------基础篇
    java基础1.JDKJDK:javadevelopmentkitJRE:javaruntimeenvironmentJDK包含JREjava跨平台:因为java程序运行依赖虚拟机,虚拟机需要有对应操作系统的版本,而jre中有虚拟机。当你想要在Linux系统下运行,则需要安装对应的虚拟机,及对应的jdk版本,而对应的jdk版本中的jre有对......
  • JAVA------基础篇
    java基础1.JDKJDK:javadevelopmentkitJRE:javaruntimeenvironmentJDK包含JREjava跨平台:因为java程序运行依赖虚拟机,虚拟机需要有对应操作系统的版本,而jre中有虚拟机。当你想要在Linux系统下运行,则需要安装对应的虚拟机,及对应的jdk版本,而对应的jdk版本中的jre有对......
  • Java-异常机制处理
     packagecom.it;importjava.util.regex.Matcher;importjava.util.regex.Pattern;publicclassTest01{publicstaticvoidmain(String[]args){test03();}publicstaticvoidtest01(){System.out.println("111");......
  • Java内存模型与可见性:volatile关键字、内存屏障与原子操作 第一章
    目录一、引言1.1定义Java内存模型(JMM)及其在并发编程中的重要性1.2简述可见性问题及其对程序正确性的影响二、Java内存模型概述2.1JMM的基本概念:主内存、工作内存、数据同步与一致性保证2.2JMM的特性:原子性、可见性、有序性2.3并发环境下常见的内存可见性问题示例......
  • WPS二次开发系列:Gradle版本、AGP插件与Java版本的对应关系
    背景最近有体验SDK的同学反馈接入SDK出现报错,最终定位到原因为接入的宿主app项目的gradle版本过低导致,SDK兼容支持了android11的特性,需要对应的gradle插件为支持android11的版本。现象解决方案将gradle版本升级至支持android11的插件版本即可,对此google官方的引文如下......
  • Java 在线反编译工具
    第一个:http://www.javadecompilers.com/该站点提供了一个用户界面,用于从.class和.jar'二进制'文件中提取源代码。推荐选择编译器:Procyonopen-source,https://bitbucket.org/mstrobel/procyon/wiki/JavaDecompilerAuthor:MikeStrobelUpdatedin2015.Handleslanguage......
  • java计算机毕业设计书店展销小程序【附源码+远程部署+程序+mysql】
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:在数字化时代,实体书店面临着前所未有的挑战。随着电子书和在线购书的普及,传统书店的销售模式受到了巨大冲击。为了适应这一变化,许多书店开始探索新的营销......