zoukankan      html  css  js  c++  java
  • JMHJava微基准线束

    一 工具简介

    官方定义:JMH is a Java harness for building, running, and analysing nano/micro/milli/macro benchmarks written in Java and other languages targeting the JVM

    JMH 主要是基于方法层面的基准测试,作为rd的我们使用它,可以评估自己代码的性能。

    二 适用场景

    1、技术插件选型:使用JMH测试具备相同功能的插件,从Throughput、Average Time等维度评估

    2、热点方法优化:对热点方法进行优化,可使用JMH对比测试,不断迭代优化

    三 操作手册

    3.1 基础概念

    • Iteration - iteration 是 JMH 进行测试的最小单位,包含一组 invocations。
    • Invocation - 一次 benchmark 方法调用。
    • Operation - benchmark 方法中,被测量操作的执行。如果被测试的操作在 benchmark 方法中循环执行,可以使用@OperationsPerInvocation表明循环次数,使测试结果为单次 operation 的性能。
    • Warmup - 在实际进行 benchmark 前先进行预热。因为某个函数被调用多次之后,JIT 会对其进行编译,通过预热可以使测量结果更加接近真实情况。

    3.2 常用注解

    序号
    注解
    用法
    说明
     
    1

    @BenchmarkMode

    1、配置 Mode 选项,可用于类(接口/枚举)或者方法上,可被继承

    2、这个注解的 value 是一个数组,可以把几种 Mode 集合在一起执行。

    如@BenchmarkMode({Mode.SampleTime, Mode.AverageTime})

    3、参数配置可以被runtime options覆盖

    Throughput-吞吐量,每秒执行了多少次方法,单位是ops/time

    AverageTime-平均响应时间(耗时),单位是time/op

    SampleTime-对所有的操作时间采样时间

    SingleShotTime-单次运行获取测量时间,一般用于测试冷起的耗时,建议把Warmup 次数设为 0(即无需预热)

    All-以上4中方式均执行一遍

     
    2

    @Benchmark

    加在方法上,标注该方法可以进行基准测试 标注的方法必须被public修饰  
    3

    @Warmup

    1、可以用在类(接口/枚举)或方法上,可被继承

    2、配置预热需要的基本参数

    3、参数配置可以被runtime options覆盖

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

    iterations-预热迭代次数,默认-1

    time-每次预热时间,默认-1

    timeUnit-预热时间单位,默认second

    batchSize-每次批量执行基准方法的个数,默认-1

     
    4

    @Threads

    1、可以用在类(接口/枚举)或方法上,可被继承

    2、参数配置可以被runtime options覆盖

    每个测试进程中,用于测试的最大线程数

    MAX-初始值-1,取值来源是Runtime.getRuntime().availableProcessors()

     
    5

    @State

    1、用在类(接口/枚举)上,可被继承

    2、定义state object在不同工作线程之间共享的范围

    state object通常作为参数注入到benchmark方法上,也可以注入到@Setup 和@TearDown 里.

    Scope.Benchmark-相同类型的实例在所有的work线程之间共享
    Scope.Group-同一组内的work线程共享相同类型的实例,每个线程组有自己的state object
    Scope.Thread-每个线程私有state object
     
    6

    @Setup

    1、只能用在方法上,不可继承

    2、在Benchmark标注的方法执行前运行,做数据初始化

    该注解只能在@state使用的类(接口/枚举)里配合使用

    Level.Trail-在每次基准运行前执行该方法
    Level.Iteration-在基准每次循环前执行该方法
    Level.Invocation-在每个基准方法执行前执行
     
    7

    @TearDown

    1、只能用在方法上,不可继承

    2、在Benchmark标注的方法执行后运行

    该注解只能在@state使用的类(接口/枚举)里配合使用

    Level.Trail-在每次基准运行后执行该方法
    Level.Iteration-在基准每次循环后执行该方法
    Level.Invocation-在每个基准方法执行后执行
     
    8 @Timeout

    1、可以用在类(接口/枚举)或方法上,可被继承

    加在方法上,仅对测试类的单一方法生效。

    加在类上,对测试类内部所有@Benchmark方法生效

    默认单位是seconds  
    9 @Param

    1、只可以用在属性声明上,可以被继承

    该注解用来标识在基准测试中可以配置化的参数,适合用来测试一个函数在不同的参数输入的情况下的性能

    1、字段不能被final修饰且类上使用了@state修饰

    2、可以用在string、枚举、基本数据类型及其包装类。取值已字符串形式给出

    举例:

    @param("1","3","5")

    private Integer num;

    3、当基准测试运行需要多个@Param时,JMH将计算运行中所有参数的外积

     
    10 @OutputTimeUnit

    1、可以用在类(接口/枚举)或方法上,可被继承

    2、用在方法上仅对该方法生效;用在类上对类内所有方法生效

    3、参数配置可以被runtime options覆盖

    配置报告结果的默认时间单位  
    11 @OperationsPerInvocation

    todo 待补充    
    12

    @GroupThreads

    1、只用在方法上,可以被继承

    定义同一组内有多少个线程运行在被注释的方法上

    默认值为1  
    13

    @Measurement

    1、可以用在类(接口/枚举)或方法上,可被继承

    2、实际基测使用的参数

    3、参数配置可以被runtime options覆盖

    跟@Warmup类似

    iterations-预热迭代次数,默认-1

    time-每次预热时间,默认-1

    timeUnit-预热时间单位,默认second

    batchSize-每次批量执行基准方法的个数,默认-1

     
    14        

    3.3 idea 使用

    3.4 使用注意点

    四 引用

    github地址:https://github.com/openjdk/jmh

    openjdk地址:http://openjdk.java.net/projects/code-tools/jmh/

    https://www.cnkirito.moe/java-jmh/

    本文来自博客园,作者:三号小玩家,转载请注明原文链接:https://www.cnblogs.com/q1359720840/p/15679734.html

  • 相关阅读:
    快速启动jar包脚本【Linux】
    解决Linux报错:/bin/bash^M: 坏的解释器: 没有那个文件或目录
    学习——nginx(2021/09/23)
    react hook中的状态管理方式
    findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of DomWrapper which is inside StrictMode.
    祝胡老师节日快乐
    vue3+ts+AntV/L7加载钻取地图
    实用的 Bash 快捷键
    react antd form 自定义表单验证validator 需要注意的细节,否则会无法触发表单提交。
    execjs
  • 原文地址:https://www.cnblogs.com/q1359720840/p/15679734.html
Copyright © 2011-2022 走看看