我有一个50米的ArrayList,我想测量存储这么多对象所需的时间.似乎所有的JMH模式都是基于时间的,我们无法真正控制@Benchmark下代码的执行数量.例如,我如何确保以下代码在每个fork上运行50万次?

@Benchmark
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(5)
public void run(BenchmarkState state) {
    try {
        state.queue.add(System.nanoTime());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

推荐答案

您可以创建基准类(ArrayListBenchmark)和runner类(BenchmarkRunner).

  • ArrayListBenchmark类中,您可以添加
  • BenchmarkRunner类中,设置要添加到的项目数

Note:根据你的环境,增加5000万件物品可能会抛出OutOfMemoryError.

基准类:

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

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;

public class ArrayListBenchmark {

    @State(Scope.Thread)
    public static class ThreadState {

        @Param({})
        private int items;

        private List<Long> list;

        @Setup(Level.Iteration)
        public void setup() {
            list = new ArrayList<>();
        }
    }

    @Benchmark
    public void addItems(ThreadState state, Blackhole blackhole) {
        blackhole.consume(addItems(state.list, state.items));
    }

    private static boolean addItems(List<Long> list, int items) {
        for (int i = 0; i < items; i++) {
            list.add(System.nanoTime());
        }
        return true;
    }

}

基准 run 者等级:

import java.util.Locale;
import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Mode;
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 org.openjdk.jmh.runner.options.TimeValue;

public class BenchmarkRunner {

    private static final String ITEMS = "items";

    private static final String N_50_000_000 = "50000000";

    public static void main(String[] args) throws RunnerException {
        runArrayListBenchmark();
    }

    public static void runArrayListBenchmark() throws RunnerException {
        Options options = new OptionsBuilder()
                .include(ArrayListBenchmark.class.getSimpleName())
                .mode(Mode.AverageTime)
                .timeUnit(TimeUnit.NANOSECONDS)
                .warmupTime(TimeValue.seconds(1))
                .warmupBatchSize(1)
                .warmupIterations(5)
                .measurementTime(TimeValue.milliseconds(100))
                .measurementBatchSize(1)
                .measurementIterations(10)
                .param(ITEMS, N_50_000_000)
                .operationsPerInvocation(Integer.parseInt(N_50_000_000))
                .threads(1)
                .forks(5)
                .shouldFailOnError(true)
                .shouldDoGC(true)
                .resultFormat(ResultFormatType.CSV)
                .result("target/" + ArrayListBenchmark.class.getSimpleName().toLowerCase(Locale.ENGLISH) + ".csv")
                .build();
        new Runner(options).run();
    }

Output:

Result "ArrayListBenchmark.addItems":
  50.023 ±(99.9%) 0.768 ns/op [Average]
  (min, avg, max) = (48.094, 50.023, 53.020), stdev = 1.551
  CI (99.9%): [49.256, 50.791] (assumes normal distribution)

Benchmark                     (items)  Mode  Cnt   Score   Error  Units
ArrayListBenchmark.addItems  50000000  avgt   50  50.023 ± 0.768  ns/op

Java相关问答推荐

如何在Inspaut中获取当前路径的 * 模式 *?

使用ExecutorService时在ThreadFactory中触发自定义newThread函数

如何在Docker容器中使用wireock—Webhooks阻止请求?

如何将kotlin代码转换为java

有关手动创建的包的问题

RESTful框架类字段是安全的还是不安全的

当我已经安装了其他版本的Java时,如何在Mac OSX 14.3.1上安装Java 6?

在Java Swing Paint应用程序中捕获快速鼠标移动时遇到困难

虚拟线程应该很快消亡吗?

为什么在下面的Java泛型方法中没有类型限制?

在使用具有不同成本的谓词调用allMatch之前对Java流进行排序会带来什么好处吗?

插入中的JOOQ序列,设置为VS值

为什么这种递归会有这样的行为?

Java.time.OffsetDateTime的SQL Server数据库列类型是什么?

为什么mvn编译生命周期阶段不只是编译已更改的java文件?

在Oracle中调用输出参数在索引处缺少IN或OUT参数的函数

用于Java的Visual Studio代码完成不起作用

基于Java中mm/dd/yy格式的最近日期对数组列表进行排序

为什么没有加载java.se模块?

设置背景时缺少Android编辑文本下划线