JMH使用

文章介绍了JMH,一个用于Java和JVM微基准测试的框架,包括依赖、关键注解的解释,如@BenchmarkMode、@State、@Warmup等,以及如何设置预热、线程数、测试次数等参数。文章还提供了示例代码,比较了不同循环方式(Streamvsfor)的性能,并展示了如何运行测试和可视化结果。
摘要由CSDN通过智能技术生成

1、依赖

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

2、注解

@BenchmarkMode

JMH能够以不同的模式来执行基准测试,JMH支持如下几种模式:

  • Throughput:吞吐率,即每秒被测试方法被执行的次数
  • Average Time:方法平均执行耗时
  • Sample Time:随机采样,展示其分布
  • Single Shot Time:只执行一次,获取其耗时,一般用于测试冷启动的性能。
@State

用于定义作用范围。

  • Scope.Benchmark:所有测试线程共享一个实例,测试有状态实例在多线程共享下的性能
  • Scope.Group:同一个线程在同一个 group 里共享实例
  • Scope.Thread:默认的 State,每个测试线程分配一个实例
@Warmup

预热配置参数。

  • iterations:预热的次数
  • time:每次预热的时间
  • timeUnit:时间的单位,默认秒
  • batchSize:批处理大小,每次操作调用几次方法
@Threads

每个测试进程的测试线程数

@Fork

进行 fork 的次数,可用于类或者方法上。如果 fork 数是 2 的话,则 JMH 会 fork 出两个进程来进行测试。

@OutputTimeUnit

测试结果的时间单位

@Measurement

实际调用方法所需要配置的一些基本测试参数

  • iterations:执行的次数。
  • time:每次执行的时间。
  • timeUnit:时间单位,默认是s。
  • batchSize:批处理大小,每次操作调用几次方法。
@Param

指定某项参数的多种情况,特别适合用来测试一个函数在不同的参数输入的情况下的性能,只能作用在字段上,使用该注解必须定义 @State 注解。

@Setup

必须标示在@State注解的类内部,表示初始化操作

@TearDown

必须表示在@State注解的类内部,表示销毁操作

3、启动

Options opt = new OptionsBuilder()
                .include(Test19.class.getSimpleName())
                .forks(1)
                .result("result1.json")
                .resultFormat(ResultFormatType.JSON)
                .build();
new Runner(opt).run();

4、可视化

JMH测试结果是一个json串,我们也可以通过一些工具进行可视化直观展示。

5、示例

@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 3, time = 1)
@Measurement(iterations = 5, time = 5)
@Threads(4)
@Fork(1)
@State(value = Scope.Benchmark)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class Test {

    public static List<String> list = Lists.newArrayList();

    static {
        for (int i = 0; i < 100; i++) {
            list.add(i + "-");
        }
    }

    @Benchmark
    public void streamtest() {
        List<String> aFor = list.stream().map(s -> new StringBuffer(s).append("for").toString()).collect(Collectors.toList());
    }

    @Benchmark
    public void fortest() {
        List<String> lis = Lists.newArrayList();
        for (String s : list) {
            lis.add(new StringBuffer(s).append("for").toString());
        }
    }


    @Benchmark
    public void fortest2() {
        List<String> lis = Lists.newArrayListWithCapacity(list.size());
        for (String s : list) {
            lis.add(new StringBuffer(s).append("for").toString());
        }
    }

    public static void main(String[] args) throws RunnerException {
        
        Options opt = new OptionsBuilder()
                .include(Test19.class.getSimpleName())
                .forks(1)
                .result("result1.json")
                .resultFormat(ResultFormatType.JSON)
                .build();
        new Runner(opt).run();
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值