JMH - 如何测量在 ArrayList 中插入 50M 项所需的时间
JMH - How to measure time it takes to insert 50M items in an ArrayList
我有一个 50M 的 ArrayList,我想测量在其中存储那么多对象所需的时间。似乎所有 JMH 模式都是基于时间的,我们无法真正控制@Benchmark 下代码的执行次数。例如,我如何确保以下代码 运行 每个 fork 恰好 50M 次?
@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();
}
}
您可以创建基准 class (ArrayListBenchmark
) 和跑步者 class (BenchmarkRunner
)。
- 在
ArrayListBenchmark
class中,可以添加benchmark方法
迭代所需的次数,将项目添加到 List
.
- 在
BenchmarkRunner
class 中,您设置了要添加到的项目的所需数量
List
并配置运行器选项。
注意:根据您的环境,添加 50M 项可能会抛出 OutOfMemoryError
.
基准 class:
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;
}
}
基准跑者class:
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();
}
输出:
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
我有一个 50M 的 ArrayList,我想测量在其中存储那么多对象所需的时间。似乎所有 JMH 模式都是基于时间的,我们无法真正控制@Benchmark 下代码的执行次数。例如,我如何确保以下代码 运行 每个 fork 恰好 50M 次?
@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();
}
}
您可以创建基准 class (ArrayListBenchmark
) 和跑步者 class (BenchmarkRunner
)。
- 在
ArrayListBenchmark
class中,可以添加benchmark方法 迭代所需的次数,将项目添加到List
. - 在
BenchmarkRunner
class 中,您设置了要添加到的项目的所需数量List
并配置运行器选项。
注意:根据您的环境,添加 50M 项可能会抛出 OutOfMemoryError
.
基准 class:
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;
}
}
基准跑者class:
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();
}
输出:
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