• 0
  • 0
分享
  • Java微基准测试神器JMH初探
  • FunTeste 2023-04-03 13:25:45 字数 2895 阅读 604 收藏 0

当我们编写一段Java代码之后,如果想知道代码性能如何,就需要进行一些快速的性能测试。

当我们实现一个需求,面临2种及以上的方案,选择一种性能更好的方案时,也需要进行一些快速的性能测试。

在之前的实践中,我一开始的测试代码通常是这样的:

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            doSomething();
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

再到后来,变成这种:

    public static void main(String[] args) {
        def test = {
                doSomething()
        }
        new FunQpsConcurrent(test, "Demo").start();
    }

但最近又有了新的工具JMH(Java Microbenchmark Harness)是用于代码微基准测试的工具套件,主要是基于方法层面的基准测试,精度可以达到纳秒级。该工具是由 Oracle 内部实现 JIT 的大牛们编写的,他们应该比任何人都了解 JIT 以及 JVM 对于基准测试的影响。

真可谓相见恨晚,上手也是非常迅速的,建议学习时间2小时,顺便看看官方GitHub仓库里面的错误示范,地址:https://github.com/lexburner/JMH-samples。

PS:

  • 如果你用的Intellij,插件是真香。
  • 如果要汇报,建议使用可视化工具,搜一下就有。

下面我分享一下我用JMH测试System.currentTimeMillis();和System.nanoTime();两个方法的性能。外行大胆猜测,第二个方法应该性能比较差。原因是第二个方法获取到纳秒时间戳,应该会更消耗性能。

这是我的测试用例:

package com.funtest.groovytest;

import com.funtester.frame.SourceCode;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.results.format.ResultFormatType;
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.concurrent.TimeUnit;

@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 2, time = 5, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS)
@Threads(2)
@Fork(1)
@State(value = Scope.Thread)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class JmhT extends SourceCode {


    @Param(value = {"10", "20", "50"})
    private int length;

    @Benchmark
    public void mill() {
        System.currentTimeMillis();
    }

    @Benchmark
    public void nano() {
        System.nanoTime();
    }

    public static void main(String[] args) throws RunnerException {
        Options options = new OptionsBuilder()
                .include(JmhT.class.getSimpleName())
                .result("result.json")
                .resultFormat(ResultFormatType.JSON)
                .forks(1)
                .threads(20)
                .warmupIterations(2)
                .warmupBatchSize(1)
                .measurementIterations(2)
                .measurementBatchSize(2)
                .build();
        new Runner(options).run();
    }

}

最后的main方法是为了生产result.json做可视化用的,如果单纯想知道性能差异,可以直接使用Intellij插件完成。用例中的length完全不用,只是想展示一下参数化的用法。

文字版测试结果如下:

Benchmark  (length)   Mode  Cnt  Score   Error   Units
JmhT.mill        10  thrpt    2  0.015          ops/ns
JmhT.mill        20  thrpt    2  0.015          ops/ns
JmhT.mill        50  thrpt    2  0.016          ops/ns
JmhT.nano        10  thrpt    2  0.091          ops/ns
JmhT.nano        20  thrpt    2  0.088          ops/ns
JmhT.nano        50  thrpt    2  0.084          ops/ns

总体看就是System.nanoTime();性能要远远优于System.currentTimeMillis();,这是不是有点意外。

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 读者提问:什么是敏捷测试?阿常回答:这个问题我从三方面回答:1、什么是敏捷测试;2、几种应用形式;3、敏捷测试的核心。一、什么是敏捷测试敏捷测试又被称为 “ 小步快跑 ”、“ 快速迭代 ”。敏捷测试就是持续地对软件质量问题进行及时地反馈。敏捷测试与传统测试的区别:传统测试交付的是一整个庞大的需求,敏捷测试交付的则是这个庞大需求的 1/N :如果把测试活动比作吃蛋糕,传统测试一次要吃整个 16寸的大蛋糕,而敏捷测试则把这块大蛋糕切成 64份,每次迭代只吃 1/64。二、几种应用形式一)每日站会每日站会,就是每天早晨 10~30 分钟的会议时间,项目组成员(包括产品、设计、研发、测试)依...
            0 0 1241
            分享
          • 作为本系列课程的最后一个模块,也是最后一节,我们将从测试用例的设计这个角度,给出我们对测试工程师一些基础能力提升方面的建议。其中的部分内容在前面课程中也或多或少的提到过,在这里也系统回顾梳理下。逻辑思维与结构思维的提高在我们对好用例的定义中,提到用例最重要的是思路的表达与呈现。缜密的逻辑,能帮助我们更好的梳理测试思路,避免遗漏;也能帮助我们更好的将思路转化成测试用例进行表达,方便其他用例阅读或执行者理解和掌握。关于逻辑思维的训练与表达,有很多相关的文章和书籍,这里推荐两个概念——金字塔原理和MECE原则。金字塔原理是一种表达结构的呈现方式,通过条理分明的拆分与梳理,将自己的想法或思考过程进行结...
            0 0 76
            分享
          • 如果想尝试着用python做一款简单好玩的小游戏"飞行的小鸟",那就得用到pygame这个模块,让我们先简单了解一下pygame吧。pygame是一个利用SDL库(全名Simple DirectMedia Layer)写就的游戏库。安装好python3环境以后,可以用pip3 install pygame命令来安装pygame。pygame有很多的模块,我们这个游戏会用到以下模块:pygame:主模块,一些通用的控制pygame.display:用来访问显示设备pygame.draw:绘制形状,线和点pygame.rect:管理矩形区域pygame.init:初始化的一些定...
            0 0 1677
            分享
          •   2022年早已过半,来个迟到的年中总结,说实话,2022,很迷茫,然后过的非常不如意,倒不是上一年的职业目标没达到,而是接下来的路根本不知道如何走。在没解决这个问题之前,或者说没搞清楚自己的方向之前,是迟迟不能落笔的,啊不,应该是落键盘。  下班后花了几天的时间研究了下测试的职业生涯规划,在许许多多的文章之中穿梭,结合前阵子和某公司t3级的大大面试,对自己接下来的几年职业规划,总算有了眉目,让恍惚的心总算有了着落。  先说我这三年坎坷的经历  刚毕业,计算机专业的我进入了软件测试这个行业,然后外包到了某bat公司,在今天看来,这间公司应该是学习资源最丰富的公司,可悲哀的是,基础能力薄弱,资...
            0 0 777
            分享
          • 1、文本框和密码框:文本框长度要求;输入内容限制;密码框(右边小眼睛):长度要求(前台控制、数据库控制、磁盘控制)输入内容限制(数字、字母、文字、特殊符号、空)不允许明文显示禁止复制粘贴两次密码要一致2、单选按钮、组合列表框、数码框单选按钮框架标题/提示文本不缺少且正确;各个选项正确;执行同一功能的多个单选按钮只能选一个;要有默认选中项;一般不能取消选中;存入后台的数据正确;存入后台的数据正确;组合列表框/下拉列表;通常单选,条目内容正确(没有多余/错放、缺少项);横向显示要完整;条目功能要正确实现;组合列表框汇总可能允许输入数据;数码框(up-down控件)能使用上下箭头控制数字变动;数字能...
            0 0 1353
            分享
      • 51testing软件测试圈微信