JMH微基准测试入门案例

JMH微基准测试入门案例JMH-javaMicrobenchmarkHarness微基准测试,他是测试某个方法的性能到底是好还是不好。这个测试框架是2013年发出来的,有JLT开发人员开发,后来归到OpenJDK下面。官网:http://openjdk.java.net/projects/code-tools/jmh/下面介绍什么是JMH,他是用来干什么的,怎么使用?基于idea中使用。创建…

大家好,又见面了,我是你们的朋友全栈君。

JMH – java Microbenchmark Harness

微基准测试,他是测试某个方法的性能到底是好还是不好。
这个测试框架是2013年发出来的,有JLT开发人员开发,后来归到OpenJDK下面。

  • 官网:http://openjdk.java.net/projects/code-tools/jmh/

下面介绍什么是JMH,他是用来干什么的,怎么使用?基于idea中使用。

创建JMH测试

1.创建maven项目,添加依赖。

1.1 jmh-core (jmh的核心)
1.2 mh-generator-annprocess(注解处理包)

 <!--jmh依赖-->
 <dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-core</artifactId>
    <version>1.21</version>
</dependency>
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>1.21</version>
    <scope>test</scope>
</dependency>

2.idea安装JMH插件JMH plugin

File->Settings->Plugins->JMH plugin

在这里插入图片描述

3. 打开运行程序注解配置

因为JMH在运行的时候他用到了注解,注解这个东西你自己得写一个程序得解释他,所以你要把这
个给设置上允许JMH能够对注解进行处理:
Compiler -> Annotation Processors -> Enable Annotation Processing(打钩)

在这里插入图片描述

4. 定义需要测试类

看这里,写了一个类,并行处理流的一个程序,定义了一个list集合,然后往这个集合里扔了1000个数。
写了一个方法来判断这个数到底是不是一个质数。
写了两个方法,第一个是用forEach来判断我们这1000个数里到底有谁是质数;第二个是使用了并行处理流。
这个forEach的方法就只有单线程里面执行,挨着从头拿到尾,从0拿到1000,但是并行处理的时候会有多个线程采用ForkJoin的方式来把里面的数分成好几份并行的尽兴处理。一种是串行处理,一种是并行处理,都可以对他们进行测试,但需要注意这个基准测试并不是对比测试的,你只是侧试一下你这方法写出这样的情况下他的吞吐量到底是多少,这是一个非常专业的测试的工具。严格的来讲这部分是测试开发专业的。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Jmh { 
   

    static List<Integer> nums = new ArrayList<>();

    static { 
   
        Random r = new Random();
        for (int i = 0; i < 10000; i++) { 
   
            nums.add(1000000 + r.nextInt(1000000));
        }
    }

    public static void foreach() { 
   
        nums.forEach(v -> isPrime(v));
    }

    static void parallel() { 
   
        nums.parallelStream().forEach(Jmh::isPrime);
    }

    static boolean isPrime(int num) { 
   
        for (int i = 2; i <= num / 2; i++) { 
   
            if (num % i == 0) return false;
        }
        return true;
    }
}

5. 写单元测试

这个测试类一定要在test package下面
我对这个方法进行测试testForEach,很简单我就调用Jmh这个类的foreach就行了,对它测试
最关键的是我加了这个注解@Benchmark,这个是JMH的注解,是要被JMH来解析处理的,
这也是我们为什么要把那个Annotation Processing给设置上的原因,非常简单,
你只要加上注解就可以对这个方法进行微基准测试了,点击右键直接run

import org.openjdk.jmh.annotations.*;

public class JmhTest { 
   
    @Benchmark
    @Warmup(iterations = 1, time = 3)//在专业测试里面首先要进行预热,预热多少次,预热多少时间
    @Fork(5)//意思是用多少个线程去执行我们的程序
    @BenchmarkMode(Mode.Throughput)//是对基准测试的一个模式,这个模式用的最多的是Throughput吞吐量
    @Measurement(iterations = 1, time = 3)//是整个测试要测试多少遍,调用这个方法要调用多少次
    public void testForEach() { 
   
        Jmh.foreach();
    }
}

在这里插入图片描述

6. 运行测试类,如果遇到下面的错误:

ERROR: org.openjdk.jmh.runner.RunnerException: ERROR: Exception while trying to acquire the JMH lock (C:\WINDOWS/jmh.lock): 拒绝访问。, exiting. Use -Djmh.ignoreLock=true to forcefully continue.
at org.openjdk.jmh.runner.Runner.run(Runner.java:216)
at org.openjdk.jmh.Main.main(Main.java:71)

这个错误是因为JMH运行需要访问系统的TMP目录,解决办法是:
打开Run Configuration -> Environment Variables -> include system environment viables(勾选)
在这里插入图片描述
最后结果:
在这里插入图片描述

JMH中的基本概念

  1. Warmup
    预热,由于JVM中对于特定代码会存在优化(本地化),预热对于测试结果很重要
  2. Mesurement
    总共执行多少次测试
  3. Timeout
  4. Threads
    线程数,由fork指定
  5. Benchmark mode
    基准测试的模式
  6. Benchmark
    测试哪一段代码

这个是JMH的一个入门,严格来讲这个和我们的关系其实并不大,这个是测试部门干的事儿,但是你了
解一下没有特别多的坏处,你也知道你的方法最后效率高或者底,可以通过一个简单的JMH插件来帮你
完成,你不要在手动的去写这件事儿了。
如果说大家对JMH有兴趣,你们在工作中可能会有用的上大家去读一下官方的例子,官方大概有好几十
个例子程序,你可以自己一个一个的去研究。
官方样例:
http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/157375.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 目标检测(降低误检测率及小目标检测系列笔记)[通俗易懂]

    目标检测(降低误检测率及小目标检测系列笔记)[通俗易懂]深度学习中,为了提高模型的精度和泛化能力,往往着眼于两个方面:(1)使用更多的数据(2)使用更深更复杂的网络。**一、什么是负样本**负样本是指不包含任务所要识别的目标的图像,也叫负图像(NegtiveImage)。以识别限速牌为例,如下所示,左图包含限速牌,为正样本,右图不包含限速牌,为背景图,即负样本。正样本负样本2.为什么要训练负样本训练负样本的目的是为了降低误检测率、误识别率,提高网络模型的泛化能力。通俗地讲就是告诉检测器,这些“不是你要检测的目标”。3.F

    2022年10月13日
    5
  • C# 串口通信 stm32 电机

    C# 串口通信 stm32 电机前几天已经完成了stm32通过PWM对电机的控制,这几天趁上班之余,也完成了c#通过串口通信控制电机的运行。界面如下好久没写文章了,发现非常不擅长分享和表达,第一反应是演示出来,可惜这里不能有动画,功能不强大啊。哪天有空了,把上位机代码和下位机代码上传上来。代码已经上传,请查看我的资源页。…

    2022年6月3日
    34
  • arduino连接lcd1602_1602显示摄氏度

    arduino连接lcd1602_1602显示摄氏度##Arduinouno连接LCD1602A显示测试温度面包板接线图代码#include<LiquifdCrystal.h>//引入依赖/*初始化针脚*/constintrs=3;constinten=5;constintd4=10;constintd5=11;constintd6=12;constintd7=13;constintlcdlight=9;//调节对比度LiquidCry

    2025年11月20日
    1
  • C++如何做字符串分割(5种方法)

    C++如何做字符串分割(5种方法)1、用strtok函数进行字符串分割原型:char*strtok(char*str,constchar*delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include<string.h>#include<stdio.h&

    2022年4月29日
    643
  • phpstrom2021.9激活码【2021最新】[通俗易懂]

    (phpstrom2021.9激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlS3…

    2022年3月26日
    48
  • BSTR LPSTR LPWSTR CString VARIANT COleVariant variant t CC

    BSTR LPSTR LPWSTR CString VARIANT COleVariant variant t CCVisualC++.NET涉及到ATL/ATLServer、MFC和托管C++等多种编程方式,不仅功能强大而且应用广泛。在编程中,我们常常会遇到ANSI、Unicode以及BSTR不同编码类型的字符串转换操作。本文先介绍基本字符串类型,然后说明相关的类,如CComBSTR、_bstr_t、CStringT等,最后讨论它们的转换方法,其中还包括使用最新ATL7.0的转换类和宏,如CA2C…

    2022年7月18日
    17

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号