我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java使用JMH进行基准性能测试分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java使用JMH进行基准性能测试分析

本篇内容主要讲解“Java使用JMH进行基准性能测试分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java使用JMH进行基准性能测试分析”吧!

    一、前言

    在日常开发工作当中,开发人员可能有这些困惑:自己写的这个方法性能到底怎么样?在原接口实现方法中添加了新的业务逻辑,对整个接口的性能影响有多少?有多种实现方式(或开源类库),到底哪一种性能更好?…

    二、JMH概述

    1、什么是JMH

      JMH,即Java Microbenchmark Harness,是专门用于代码微基准测试的工具套件。何谓Micro Benchmark呢?简单的来说就是基于方法层面的基准测试,精度可以达到微秒级。其由Oracle/openjdk内部开发JIT编译器的大佬们所开发,作为java的方法级性能测试工具可以说是根正苗红了。(官方地址:http://hg.openjdk.java.net/code-tools/jmh/ )

    2、JMH适用的典型场景

      a、优化热点方法,准确的知道某个方法的执行耗时,以及不同入参与最终实际耗时的关系,从而针对性的进行优化;
      b、寻找最佳方案,验证接口方法不同实现方式的实际吞吐量,从而确定最佳实现方式 。如:选择json转换工具时选fastjson还是gson、字符串连接使用StringBuilder方式还是直接相加;
      c、分析性能损耗,在原接口方法业务逻辑中添加新的业务代码时,对整个业务方法的性能影响。如:在原业务逻辑中,添加一个插入操作日志的操作,可以分析新加操作对整个业务方法的性能影响。
      d、分析百分比内的耗时,即测试方法多次调用时百分比区间内的耗时,如:测试调用某个方法,50%以内的调用耗时是8.2ms/op,90%以内是9.3ms/op,99.99%以内是10.2ms/op,等等。(模式为Mode.SampleTime)

    3、JMH基本概念

      a、Mode :表示JMH测试中的模式,默认有5种,分别是Throughput(吞吐量)、AverageTime(平均耗时)、SampleTime(随机采样)、SingleShotTime(单次执行)、All(以上4种都来一次);
      b、Fork:表示JMH将用来测试的进程数;
      c、Warmup : 表示预热,在HotSpot中,JVM的JIT编译器会对热点代码进行编译优化, 因此为了最接近真实的情况,需要先预热测试代码,使JIT编译器完成可能需要的优化,从而令JMH最终测试结果更加准确;
      d、Iteration :表示JMH中的最小测试迭代单位,即测试次数,一般默认值是每次1s;
      e、Benchmark:用于标注JMH将进行测试的方法。(类似Junit中的@Test注解)

    三、JMH的使用

    1、快速跑起来

      JMH的基本使用只需2步,第1步是引入maven依赖包,第2步是根据工具框架模板编写测试类,以下通过一个简单例子进行详细说明:

    例1:测试一个方法的平均耗时

    引入maven依赖: (笔者使用的jmh版本为1.21)

    <!-- JMH --><dependency>    <groupId>org.openjdk.jmh</groupId>    <artifactId>jmh-core</artifactId>    <version>${jmh.version}</version></dependency><dependency>    <groupId>org.openjdk.jmh</groupId>    <artifactId>jmh-generator-annprocess</artifactId>    <version>${jmh.version}</version>    <scope>provided</scope></dependency>

    编写测试方法:

    package com.xiaojiang;import org.openjdk.jmh.annotations.Benchmark;import org.openjdk.jmh.annotations.BenchmarkMode;import org.openjdk.jmh.annotations.Mode;import org.openjdk.jmh.annotations.OutputTimeUnit;import org.openjdk.jmh.runner.Runner;import org.openjdk.jmh.runner.options.Options;import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.concurrent.TimeUnit;@OutputTimeUnit(TimeUnit.MILLISECONDS)@BenchmarkMode(Mode.AverageTime)public class JmhDemoOne {    public static void main(String[] args) throws Exception{        Options options = new OptionsBuilder()                .include(JmhDemoOne.class.getName())                .build();        new Runner(options).run();    }        @Benchmark    public void sayHello() throws Exception{        //TODO 业务方法 ,此处用休眠的方式模拟业务耗时10 ms        TimeUnit.MILLISECONDS.sleep(10);    }}

    代码说明:

    通过以上例子可以发现,一个基本的JMH测试实现其实并不是很复杂,非常类似于用Junit做单元测试。具体说明如下:
      a、类名JmhDemoOne 上的@OutputTimeUnit、@BenchmarkMode这两个注解,表明这是一个JMH的测试类;(具体注解含义 ,以及更多注解说明请参考下文JMH常用注解详细介绍)
      b、主函数入口main方法中指定了一些基本测试参数选项;(基本就是固定写法。其实有更多相关参数方法可以添加,但这些参数笔者建议通过注解的方式在类上直接添加,这样来的更加方便)
      c、通过@Benchmark注解标注需要benchmark(基准测试)的具体方法;

    直接运行测试方法,控制台输出测试结果如下:(笔者JDK版本为1.8,IDE工具为IDEA2018)

    # JMH version: 1.21# VM version: JDK 1.8.0_144, Java HotSpot(TM) 64-Bit Server VM, 25.144-b01# VM invoker: D:\Java\jdk1.8.0_144\jre\bin\java.exe# VM options: -javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=55987:D:\Program Files\JetBrains\IntelliJ IDEA 2018.2.5\bin -Dfile.encoding=UTF-8# Warmup: 5 iterations, 10 s each# Measurement: 5 iterations, 10 s each# Timeout: 10 min per iteration# Threads: 1 thread, will synchronize iterations# Benchmark mode: Average time, time/op# Benchmark: com.xiaojiang.JmhDemoOne.sayHello# Run progress: 0.00% complete, ETA 00:08:20# Fork: 1 of 5# Warmup Iteration   1: 10.716 ms/op# Warmup Iteration   2: 10.640 ms/op# Warmup Iteration   3: 10.737 ms/op# Warmup Iteration   4: 10.693 ms/op# Warmup Iteration   5: 10.723 ms/opIteration   1: 10.716 ms/opIteration   2: 10.724 ms/opIteration   3: 10.772 ms/opIteration   4: 10.758 ms/opIteration   5: 10.709 ms/op# Run progress: 20.00% complete, ETA 00:06:43# Fork: 2 of 5# Warmup Iteration   1: 10.744 ms/op# Warmup Iteration   2: 10.732 ms/op# Warmup Iteration   3: 10.748 ms/op# Warmup Iteration   4: 10.728 ms/op# Warmup Iteration   5: 10.760 ms/opIteration   1: 10.701 ms/opIteration   2: 10.709 ms/opIteration   3: 10.719 ms/opIteration   4: 10.714 ms/opIteration   5: 10.703 ms/op# Run progress: 40.00% complete, ETA 00:05:02# Fork: 3 of 5# Warmup Iteration   1: 10.729 ms/op# Warmup Iteration   2: 10.731 ms/op# Warmup Iteration   3: 10.728 ms/op# Warmup Iteration   4: 10.700 ms/op# Warmup Iteration   5: 10.709 ms/opIteration   1: 10.708 ms/opIteration   2: 10.701 ms/opIteration   3: 10.708 ms/opIteration   4: 10.726 ms/opIteration   5: 10.698 ms/op# Run progress: 60.00% complete, ETA 00:03:21# Fork: 4 of 5# Warmup Iteration   1: 10.724 ms/op# Warmup Iteration   2: 10.688 ms/op# Warmup Iteration   3: 10.748 ms/op# Warmup Iteration   4: 10.732 ms/op# Warmup Iteration   5: 10.772 ms/opIteration   1: 10.729 ms/opIteration   2: 10.688 ms/opIteration   3: 10.705 ms/opIteration   4: 10.687 ms/opIteration   5: 10.709 ms/op# Run progress: 80.00% complete, ETA 00:01:40# Fork: 5 of 5# Warmup Iteration   1: 10.688 ms/op# Warmup Iteration   2: 10.696 ms/op# Warmup Iteration   3: 10.692 ms/op# Warmup Iteration   4: 10.684 ms/op# Warmup Iteration   5: 10.683 ms/opIteration   1: 10.719 ms/opIteration   2: 10.720 ms/opIteration   3: 10.695 ms/opIteration   4: 10.710 ms/opIteration   5: 10.760 ms/opResult "com.xiaojiang.JmhDemoOne.sayHello":  10.716 ±(99.9%) 0.016 ms/op [Average]  (min, avg, max) = (10.687, 10.716, 10.772), stdev = 0.021  CI (99.9%): [10.700, 10.731] (assumes normal distribution)# Run complete. Total time: 00:08:24REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up onwhy the numbers are the way they are. Use profilers (see -prof, -lprof), design factorialexperiments, perform baseline and negative tests that provide experimental control, make surethe benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.Do not assume the numbers tell you what you want them to tell.Benchmark            Mode  Cnt   Score   Error  UnitsJmhDemoOne.sayHello  avgt   25  10.716 ± 0.016  ms/opProcess finished with exit code 0

    测试结果说明:
    整个测试结果分为3大块,测试基本参数信息、测试过程、测试结果,各行含义具体说明如下:

    说明
    参数信息(1-10行)1:jmh版本
    2:jvm版本信息
    3:jvm程序(jdk安装路径)
    4:jvm参数配置
    5:预热参数:预热次数、每次持续时间
    6:测试参数:测试次数、每次持续时间
    7:每次测试迭代超时时间
    8:每个测试进程的测试线程数
    9: 测试的模式
    10:测试的方法
    测试过程(12-75行)12-23:第1次fork测试 (fork可以理解为1个独立的进程)
    12:测试完成进度,预计剩余需要时间
    13:当前第几次fork
    14-18:预热执行,每次预热执行耗时
    19-23:正式测试执行,每次测试执行耗时
    25-36:第2次fork测试
    38-49:第3次fork测试
    51-62:第4次fork测试
    64-75:第5次fork测试
    测试结果(78-95行)78-81:测试结果,包括测试的方法、平均耗时[平局耗时的比例]、最大最小 耗时、测试结果数据离散度(stdev)等
    84:测试总耗时
    86-90:对测试结果的解释
    92-93:测试结论{测试的方法、测试类型(Mode)、测试总次数(Cnt)、测试结果(Score)、误差(Error)、单位(Units)}
    95:结束

     注:
      a、测试结果中的Measurement、Fork、Warmup等参数,是JMH采用了默认的配置值,实际使用中,我们可根据需要指定相关参数。
      b、运行这个测试类可以在IDEA中直接跑,也可以打成 jar 包到服务器上跑。
      c、本测试结果是直接输出在控制台,如有需要,可将测试结果输出到文件中,方法是在options中添加output方法指定测试结果输出目录,如下:

    Options options = new OptionsBuilder()        .include(JmhDemoOne.class.getName())        .output("D:/JmhDemoOne.log")   //将测试结果输出到指定目录文件        .build();

    2、JMH常用注解详细介绍

    注解介绍
    @BenchmarkMode基准测试模式。一共有5种可选值:(其实是4种)
    Mode.Throughput:吞吐量模式,即单位时间内方法的吞吐量
    Mode.AverageTime:平均耗时模式,即一定测试次数内方法执行的平均耗时
    Mode.SampleTime:随机采样模式,即最终结果为取样结果分布比例
    Mode.SingleShotTime:单次执行模式,即只会执行一次(以上的模式通常会有预热、会迭代执行多次,这个模式可用于测试某些特定场景,如冷启动时的性能)
    Mode.All:即以上模式都执行一遍

    -----------------------------------
    用法示例:(benchmark模式为平均耗时模式)
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit测试结果的时间单位。其值为java.util.concurrent.TimeUnit 枚举中的值,通常用的值是秒、毫秒、微妙(需要注意的是,在不同测试模式下,需要选择合适的时间单位,从而获取更精确的测试结果。)

    ------------------------------------
    用法示例:(benchmark结果时间单位为毫秒)
    @OutputTimeUnit(TimeUnit.MILLISECONDS)
    @Benchmark基准测试,方法级注解(配置在方法名上)。用于标注需要进行benchmark (基准测试)的方法

    ------------------------------------
    用法示例:(方法需要benchmark)
    @Benchmark
    @Warmup预热参数。配置预热的相关参数,参数含义是:iterations(预热次数)、time (预热时间)、timeUnit (时间单位)

    ------------------------------------
    用法示例:(预热10次,每次20s)
    @Warmup(iterations = 10, time = 20, timeUnit = TimeUnit.SECONDS)
    @Measurement度量,即benchmark基本参数。参数含义是:iterations(测试次数)、time (每次测试时间)、timeUnit (时间单位)

    ------------------------------------
    用法示例:(测试5次,每次30s)
    @Measurement(iterations = 5, time = 30, timeUnit = TimeUnit.SECONDS)
    @Fork分叉,即进程数。用于配置将使用多少个进程进行测试

    ------------------------------------
    用法示例:(使用3个进程)
    @Fork(3)
    @Threads线程数。每个Fork(进程)中的线程数,一般可设为测试机器cpu核心数。

    ------------------------------------
    用法示例:(使用4个线程)
    @Threads(4)
    @Param成员参数,属性级注解。用于测试方法在不同入参情况下的性能表现。

    ------------------------------------
    用法示例:(入参值依次为1 、10、100)
    @Param({“1”, “10”, “100”})
    @Setup设置,方法级注解。用于标注benchmark前的操作,通常用于测试前初始化参数资源,如初始化数据库连接等。

    ------------------------------------
    用法示例:(初始化方法)
    @Setup
    @TearDown拆卸,方法级注解。用于标注benchmark后的操作,通常用于测试后回收资源,如关闭数据库连接等。

    ------------------------------------
    用法示例:(回收方法)
    @TearDown
    @State状态,表示一个类/方法的可用范围,其值有3个:
    Scope.Thread:默认状态,每个线程分配一个独享的实例;
    Scope.Benchmark:测试中的所有线程共享实例;(多线程测试情况下)
    Scope.Group:同一个组的线程共享实例;

    ------------------------------------
    用法示例:(默认值,每个线程分配一个实例)
    @State(Scope.Thread)
    @Group测试组,方法级注解。适用分组测试,每组线程数不一样的场景。

    ------------------------------------
    用法示例:(组名为“group_name”的一个组)
    @Group(“group_name”)
    @GroupThreads组线程数,方法级注解。通常和@Group搭配使用

    ------------------------------------
    用法示例:(组线程数为10)
    @GroupThreads(10)
    @Timeout超时时间。每次测试迭代超时时间

    ------------------------------------
    用法示例:(每次测试超时时间为20min)
    @Timeout(time = 20, timeUnit = TimeUnit.MINUTES)

    以上是使用JMH测试中常用的注解,当然JMH还有一些其它注解,如@CompilerControl、@AuxCounters 等等,这些注解通常可用于满足特定的测试场景需求,具体相关使用如有需要,可参考官方示例,官方demo比较详细,比较好理解学习。

    3、更多示例

    本小节笔者将通过几个小示例,展示JMH的基本使用。
    例2:
    测试验证字符串连接处理时,使用StringBuilder方式是否比直接相加好。

    package com.xiaojiang;import org.openjdk.jmh.annotations.*;import org.openjdk.jmh.runner.Runner;import org.openjdk.jmh.runner.options.Options;import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.concurrent.TimeUnit;@OutputTimeUnit(TimeUnit.SECONDS)@BenchmarkMode(Mode.Throughput)@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.MILLISECONDS)@Measurement(iterations = 10, time = 5, timeUnit = TimeUnit.SECONDS)@State(Scope.Thread)public class JmhDemoTwo {    public static void main(String[] args) throws Exception{        Options options = new OptionsBuilder()                .include(JmhDemoTwo.class.getName())                .build();        new Runner(options).run();    }        @Param({"10", "100", "1000"})    private int number;        @Benchmark    public void StringAddMode(){        String str = "";        for(int i=0;i<number;i++){            str = str + i;        }    }        @Benchmark    public void StringBuilderMode(){        StringBuilder sb = new StringBuilder();        for(int i=0;i<number;i++){            sb.append(i);        }    }}

    测试结果:

    //---省略测试过程结果----------
    Benchmark                     (number)   Mode  Cnt         Score        Error  Units
    JmhDemoTwo.StringAddMode            10  thrpt   50   7670608.558 ±  99068.181  ops/s
    JmhDemoTwo.StringAddMode           100  thrpt   50    437133.436 ±   7738.031  ops/s
    JmhDemoTwo.StringAddMode          1000  thrpt   50      4023.846 ±     62.872  ops/s
    JmhDemoTwo.StringBuilderMode        10  thrpt   50  22608867.036 ± 669332.843  ops/s
    JmhDemoTwo.StringBuilderMode       100  thrpt   50   1232847.661 ±  23742.088  ops/s
    JmhDemoTwo.StringBuilderMode      1000  thrpt   50     98367.745 ±   1487.840  ops/s

    从测试结果可以看出,在字符串连接数量分别为10、100、1000时,通过StringBuilder处理字符串的方式比直接相加的方式性能都要强一些;如,当字符窜数量为1000时,直接相加方式的方法吞吐量为4023.846 ops/s,StringBuilder的方式方法吞吐量达到 98367.745ops/s 。(当然具体测试结果值和机器配置、JVM配置有关)

    例3:
    测试常用序列化json库fastJson、gson、jackson的性能(均为截止2019.06最新版本)。

    package com.xiaojiang;import org.openjdk.jmh.annotations.*;import org.openjdk.jmh.runner.Runner;import org.openjdk.jmh.runner.options.Options;import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.concurrent.TimeUnit;@OutputTimeUnit(TimeUnit.MILLISECONDS)@BenchmarkMode(Mode.SingleShotTime)@Warmup(iterations = 5)@Measurement(iterations = 1)@State(Scope.Benchmark)@Fork(1)public class JmhDemoThree {    public static void main(String[] args) throws Exception{        Options options = new OptionsBuilder()                .include(JmhDemoThree.class.getName())                .build();        new Runner(options).run();    }        @Param({"100", "10000", "1000000"})    private int number;    private Userinfo userinfo;    private String fastjson_jsonStr;    private String gson_jsonStr;    private String jackson_jsonStr;        @Benchmark    public void fastjson_bean2Json(){        for (int i=0;i<number;i++){            JsonUtil.fastjson_bean2Json(userinfo);        }    }        @Benchmark    public void gson_bean2Json(){        for (int i=0;i<number;i++){            JsonUtil.gson_bean2Json(userinfo);        }    }        @Benchmark    public void jackson_bean2Json(){        for (int i=0;i<number;i++){            JsonUtil.jackson_bean2Json(userinfo);        }    }        @Benchmark    public void fastjson_json2Bean(){        for (int i=0;i<number;i++){            JsonUtil.fastjson_json2Bean(fastjson_jsonStr,Userinfo.class);        }    }        @Benchmark    public void gson_json2Bean(){        for (int i=0;i<number;i++){            JsonUtil.gson_json2Bean(gson_jsonStr,Userinfo.class);        }    }        @Benchmark    public void jackson_json2Bean(){        for (int i=0;i<number;i++){            JsonUtil.jackson_json2Bean(jackson_jsonStr,Userinfo.class);        }    }        @Setup    public void init(){         userinfo = new Userinfo();        userinfo.setUsername("张三");        userinfo.setGender("男");        userinfo.setAge(18);        userinfo.setBirthday(new Date());        userinfo.setCreateTime(System.currentTimeMillis());        List<String> list = new ArrayList<>();        list.add("北京三里屯儿那条街那条巷那一号");        list.add("上海三里屯儿那条街那条巷那一号");        list.add("深圳三里屯儿那条街那条巷那一号");        userinfo.setAddress(list);                fastjson_jsonStr = JsonUtil.fastjson_bean2Json(userinfo);        gson_jsonStr = JsonUtil.gson_bean2Json(userinfo);        jackson_jsonStr = JsonUtil.jackson_bean2Json(userinfo);    }}

    (其它相关代码后附)

    测试结果:

    //---省略测试过程结果----------
    Benchmark                        (number)  Mode  Cnt     Score   Error  Units
    JmhDemoThree.fastjson_bean2Json       100    ss          1.586          ms/op
    JmhDemoThree.fastjson_bean2Json     10000    ss          3.683          ms/op
    JmhDemoThree.fastjson_bean2Json   1000000    ss        500.924          ms/op
    JmhDemoThree.fastjson_json2Bean       100    ss          0.978          ms/op
    JmhDemoThree.fastjson_json2Bean     10000    ss          5.493          ms/op
    JmhDemoThree.fastjson_json2Bean   1000000    ss        362.337          ms/op
    JmhDemoThree.gson_bean2Json           100    ss          2.106          ms/op
    JmhDemoThree.gson_bean2Json         10000    ss         28.693          ms/op
    JmhDemoThree.gson_bean2Json       1000000    ss       1890.999          ms/op
    JmhDemoThree.gson_json2Bean           100    ss          7.175          ms/op
    JmhDemoThree.gson_json2Bean         10000    ss        110.298          ms/op
    JmhDemoThree.gson_json2Bean       1000000    ss       7310.555          ms/op
    JmhDemoThree.jackson_bean2Json        100    ss          2.111          ms/op
    JmhDemoThree.jackson_bean2Json      10000    ss          8.859          ms/op
    JmhDemoThree.jackson_bean2Json    1000000    ss        376.587          ms/op
    JmhDemoThree.jackson_json2Bean        100    ss          1.992          ms/op
    JmhDemoThree.jackson_json2Bean      10000    ss         10.723          ms/op
    JmhDemoThree.jackson_json2Bean    1000000    ss        714.569          ms/op

    从测试结果可以看出,不论是bean2Json还是json2Bean,fastjson的性能比gson、jackson都要好一些,当然,jackson性能也很不错(不愧是spring默认的序列化和反序列化工具),尤其是当序列化与反序列化次数较多时,fastjson优势尤其明显。当然,由于笔者用于测试的实体bean数据结构还是较为简单,在一些较为复杂的数据结构场景下,其各自的性能表现可能有所不一样。(笔者用的测试Mode是Mode.SingleShotTime,只测试一次,且由于机器等原因,所以误差可能相对较大。有兴趣的读者,可以测试一下不同测试Mode下,更复杂的数据结构场景下,各序列化/反序列化工具的性能表现)

    四、小结

    JMH官方并没有提供比较详细的使用文档(这也是笔者整理本文的重要原因),但是其提供了许多详细、较容易理解的例子,有问题的可以参考,地址为:http://hg.openjdk.java.net/code-tools/jmh/file/99d7b73cf1e3/jmh-samples/class="lazy" data-src/main/java/org/openjdk/jmh/samples 。
    2、JMH中的参数配置,许多参数可以直接在main方法的options中设置,也可以通过在类上直接添加注解配置。
    3、注意:跑测试的时候要直接用run的方式跑,不要用debug的方式跑,否则会出错。
    4、JMH适用于方法级别的基准性能测试,并不适用于跨系统、跨服务之间的全链路测试。
    5、使用JMH基准测试,虽然精度可以达到微妙级,但是测试结果依然是会存在一定误差的;由于测试机器、场景、jvm配置等不同而引起测试误差是完全可能的,只是这个误差能否在可接受的范围内。
    6、最终测试结果是fork参数与每次测试迭代参数的合集,如fork值为3,iterations值为5,那最终测试次数就是 3 * 5 = 15次。

    参考文章:
    http://hg.openjdk.java.net/code-tools/jmh/file/99d7b73cf1e3/jmh-samples/class="lazy" data-src/main/java/org/openjdk/jmh/samples
    http://java-performance.info/jmh/
    https://www.cnblogs.com/tranquillity/p/9488572.html
    https://www.xncoding.com/2018/01/07/java/jmh.html
    https://blog.csdn.net/lxbjkben/article/details/79410740
    http://blog.dyngr.com/blog/2016/10/29/introduction-of-jmh/
    http://irfen.me/java-jmh-simple-microbenchmark/
    https://www.cnblogs.com/bestzhang/p/10082119.html

    附:

    json工具pom依赖:

    <!--fastJson--><dependency>    <groupId>com.alibaba</groupId>    <artifactId>fastjson</artifactId>    <version>1.2.58</version></dependency><!--gson--><dependency>    <groupId>com.google.code.gson</groupId>    <artifactId>gson</artifactId>    <version>2.8.5</version></dependency><!--jackson--><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-databind</artifactId>    <version>2.9.9</version></dependency><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-core</artifactId>    <version>2.9.9</version></dependency><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-annotations</artifactId>    <version>2.9.9</version></dependency>

    Userinfo.java:

    package com.xiaojiang;import java.util.Date;import java.util.List;public class Userinfo {    private String username;    //用户名    private String gender;      //用户性别    private Integer age;    //用户年龄    private Date birthday;      //用户生日    private List<String> address;   //  用户地址    private Long createTime;    //用户创建时间    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    public String getGender() {        return gender;    }    public void setGender(String gender) {        this.gender = gender;    }    public Integer getAge() {        return age;    }    public void setAge(Integer age) {        this.age = age;    }    public Date getBirthday() {        return birthday;    }    public void setBirthday(Date birthday) {        this.birthday = birthday;    }    public List<String> getAddress() {        return address;    }    public void setAddress(List<String> address) {        this.address = address;    }    public Long getCreateTime() {        return createTime;    }    public void setCreateTime(Long createTime) {        this.createTime = createTime;    }    @Override    public String toString() {        return "Userinfo{" +                "username='" + username + '\'' +                ", gender='" + gender + '\'' +                ", age=" + age +                ", birthday=" + birthday +                ", address=" + address +                ", createTime=" + createTime +                '}';    }}

    JsonUtil.java:

    package com.xiaojiang;import com.alibaba.fastjson.JSON;import com.fasterxml.jackson.core.JsonProcessingException;import java.io.IOException;public class JsonUtil {    private static com.google.gson.Gson gson = new com.google.gson.GsonBuilder().create();    private static com.fasterxml.jackson.databind.ObjectMapper jacksonMapper = new com.fasterxml.jackson.databind.ObjectMapper();    public static String fastjson_bean2Json(Object object){        return com.alibaba.fastjson.JSON.toJSONString(object);    }    public static <T> T fastjson_json2Bean(String jsonStr, Class<T> objectClass) {        return JSON.parseObject(jsonStr, objectClass);    }    public static String gson_bean2Json(Object object){        return gson.toJson(object);    }    public static <T> T gson_json2Bean(String jsonStr, Class<T> objectClass){        return gson.fromJson(jsonStr,objectClass);    }    public static String jackson_bean2Json(Object object) {        try {            return jacksonMapper.writeValueAsString(object);        } catch (JsonProcessingException e) {            e.printStackTrace();        }        return null;    }    public static <T> T jackson_json2Bean(String jsonStr, Class<T> objectClass){        try {            return jacksonMapper.readValue(jsonStr,objectClass);        } catch (IOException e) {            e.printStackTrace();        }        return null;    }}

    到此,相信大家对“Java使用JMH进行基准性能测试分析”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    Java使用JMH进行基准性能测试分析

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    Java使用JMH进行基准性能测试分析

    本篇内容主要讲解“Java使用JMH进行基准性能测试分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java使用JMH进行基准性能测试分析”吧!一、前言在日常开发工作当中,开发人员可能有这些困
    2023-06-25

    Java基准性能测试之JMH的示例分析

    这篇文章主要为大家展示了“Java基准性能测试之JMH的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java基准性能测试之JMH的示例分析”这篇文章吧。一、JMH vs JMeterJ
    2023-06-20

    Java微基准测试框架JMH怎么使用

    使用Java微基准测试框架JMH需要按照以下步骤进行:1. 创建一个Java项目,并将JMH依赖添加到项目的构建文件中(例如,Maven的pom.xml文件)。```xmlorg.openjdk.jmhjmh-core1.27org.ope
    2023-09-22

    如何对 C++ 函数性能进行基准测试?

    为 c++++ 函数进行基准测试,可采取以下步骤:使用计时工具(如 std::chrono 库)测量执行时间。编写基准测试函数以执行代码并返回执行时间。利用基准测试库获取高级功能,如统计收集和比较。如何对 C++ 函数性能进行基准测试基准
    如何对 C++ 函数性能进行基准测试?
    2024-04-19

    怎么用PL/SQL进行数据库性能基准测试

    要使用PL/SQL进行数据库性能基准测试,可以按照以下步骤进行:创建测试表:首先,创建一个测试表来存储测试数据。可以使用以下SQL语句创建一个简单的测试表:CREATE TABLE test_table (id NUMBER,name VA
    怎么用PL/SQL进行数据库性能基准测试
    2024-05-08

    怎么使用HammerDB进行MySQL基准测试

    使用HammerDB进行MySQL基准测试的步骤如下:首先,下载并安装HammerDB。你可以在HammerDB的官方网站(https://www.hammerdb.com/)上找到最新的版本,并根据操作系统的要求进行安装。启动Hammer
    2023-10-24

    在Golang的高并发场景中如何进行基准测试和性能分析?

    为了在 go 的高并发场景中进行基准测试和性能分析,您可以采取以下步骤:使用 go test 工具进行基准测试,以测量代码在特定条件下的性能。使用 go tool pprof 工具进行性能分析,以深入调查代码的内部行为和性能模式。通过以下方
    在Golang的高并发场景中如何进行基准测试和性能分析?
    2024-05-10

    怎么使用HammerDB进行MySQL基准测试

    HammerDBHammerDB是一种开源MySQL基准测试工具,用于评估数据库性能。它提供多种测试场景和指标,让数据库管理员了解系统瓶颈。HammerDB可识别连接限制、CPU使用率高和延迟,并提供优化配置的建议。通过比较结果,可以监控性能改进。遵循最佳实践(如在测试环境中运行和使用真实数据)以确保准确的基准测试。
    怎么使用HammerDB进行MySQL基准测试
    2024-04-12

    如何使用HammerDB进行MySQL基准测试

    使用HammerDB进行MySQL基准测试HammerDB是一款开源工具,可用于对MySQL数据库执行负载测试和基准测试。它模拟真实世界负载,提供有关MySQL性能和可扩展性的见解。配置和运行:安装HammerDB并对其进行配置以连接到MySQL数据库。通过运行一个命令启动基准测试,实时监视指标并记录结果。分析和改进:分析HammerDB报告以识别性能瓶颈和进行改进。高级功能允许进行可自定义负载测试、并行测试和定制指标监视。最佳实践:使用类似于生产环境的硬件,逐步增加负载,并重复基准测试以获得准确的结果。
    如何使用HammerDB进行MySQL基准测试
    2024-04-13

    Go函数性能优化:基准测试与性能分析方法

    了解 go 函数性能优化至关重要,可以通过以下方法实现:基准测试:使用 go 的 testing 包测量执行时间和资源消耗,例如基准测试字符串连接策略。性能分析:使用 runtime/pprof 包生成函数调用图,通过 go tool pp
    Go函数性能优化:基准测试与性能分析方法
    2024-05-03

    使用traceview进行Android性能测试

    一、 TraceView工具简述Traceview是android平台配备的一个很好的性能分析工具。它可以通过图形界面的方式让我们了解我们要跟踪的程序的性能,并且能具体到method。二、 TraceView工具使用方法TraceView有
    2022-06-06

    如何使用Gateling进行性能测试

    这篇文章主要讲解了“如何使用Gateling进行性能测试”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用Gateling进行性能测试”吧!Gatling是什么?Gatling 是一个用
    2023-06-02

    使用Apache ab进行http性能测试

    Mac自带了Apache环境 打开“终端(terminal)”,输入 sudo apachectl -v,(可能需要输入机器秘密)。如下显示Apache的版本接着输入 sudo apachectl start,这样Apache就启动了。打开
    2022-06-04

    如何使用BenchmarkDotNet对C#代码进行基准测试

    这篇文章给大家分享的是有关如何使用BenchmarkDotNet对C#代码进行基准测试的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。BenchmarkDotNet 是一个轻量级,开源的,强大的 .NET 工具包,
    2023-06-14

    如何使用基准测试优化golang函数性能

    基准测试是优化 go 函数性能的有效工具。基准测试语法包括:创建基准测试函数(以 benchmarkxxx 命名)、重置计时器(b.resettimer())、报告内存分配(b.reportallocs())和停止计时器(b.stoptim
    如何使用基准测试优化golang函数性能
    2024-04-27

    python如何使用cProfile针对回测进行性能分析

    这篇文章主要讲解了“python如何使用cProfile针对回测进行性能分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python如何使用cProfile针对回测进行性能分析”吧!安装不
    2023-06-02

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录