我使用JMH对JUnit测试进行基准测试。
我的基准:
import org.openjdk.jmh.annotations.*;
public class Benchmarks {
@Benchmark
public void bmUnitTest1() {
UnitTests.UnitTest1();
}
@Benchmark
public void bmUnitTest2() {
UnitTests.UnitTest2();
}
}我的基准跑步者:
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.TimeValue;
import java.util.concurrent.TimeUnit;
public class BenchmarkRunner {
public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(Benchmarks.class.getSimpleName())
.mode(Mode.SingleShotTime)
.resultFormat(ResultFormatType.CSV)
.result("target/test-classes/benchmarkcsv/BM " + System.currentTimeMillis() + ".csv")
.timeUnit(TimeUnit.MILLISECONDS)
.warmupIterations(3)
.warmupTime(TimeValue.seconds(1))
.measurementIterations(3)
.measurementTime(TimeValue.seconds(1))
.timeout(TimeValue.seconds(5))
.forks(1)
.warmupForks(1)
.threads(1)
.build();
new Runner(opt).run();
}
}目前,我正在获得整个单元测试的性能指标。我想知道是否有可能在较低的级别上看到这些性能指标。
示例:
UnitTest1有多个函数调用。Function1需要10,Function2需要20。
而不是看到这个(简化):
UnitTest1: 30ms/op我想看看这个:
UnitTest1: 30ms/op
Function1: 10ms/op
Function2: 20ms/op我能用JMH做这个吗?如果没有,我是否可以使用其他方法对JUnit测试进行基准测试?
发布于 2022-04-23 20:17:22
JMH有几个分析器,可以在运行基准时启用。详情请参见剖面仪。
其中之一是基于async项目的异步分析器分析器。它可以做您想做的事情-显示单元测试调用的方法占用了大部分CPU时间(具有堆栈跟踪!)
若要启用此探查器,请调用OptionsBuilder.addProfiler(AsyncProfiler.class, "output=flamegraph"),或者(如果从命令行运行)添加-prof async:output=flamegraph选项。
当基准测试完成后,JMH将生成一个.html格式的分析器报告:

如果您想要获得一个平面配置文件--只是使用占CPU时间百分比的方法--使用async分析器而不使用output选项:
ns percent samples top
---------- ------- ------- ---
1992741308 39.53% 200 java.util.stream.AbstractPipeline.copyInto
844434060 16.75% 84 java.util.stream.StreamOpFlag.isKnown
670418795 13.30% 67 java.lang.Integer.max
500609106 9.93% 50 java.util.stream.AbstractPipeline.getStreamAndOpFlags
451255844 8.95% 45 java.util.stream.AbstractPipeline.evaluate
221004309 4.38% 22 java.util.stream.ReduceOps$7.makeSink
140062540 2.78% 14 java.util.Spliterators$IntArraySpliterator.forEachRemaining
60012022 1.19% 6 java.util.stream.AbstractPipeline.wrapSink
39966227 0.79% 4 java.util.stream.ReduceOps$6ReducingSink.accept
39348309 0.78% 4 java.util.stream.ReduceOps$ReduceOp.evaluateSequential
10862017 0.22% 1 Dictionary::find(unsigned int, Symbol*, Handle)
10637320 0.21% 1 ciVirtualCallTypeData::translate_from(ProfileData const*)
10209263 0.20% 1 java.util.stream.AbstractPipeline.<init>
10155044 0.20% 1 java.util.Spliterator$OfInt.forEachRemaining
10128043 0.20% 1 PhaseChaitin::Register_Allocate()
10115108 0.20% 1 _raw_spin_unlock_irqrestore_[k]
9486501 0.19% 1 PhaseChaitin::Select()
9281194 0.18% 1 PhaseIdealLoop::optimize(PhaseIterGVN&, LoopOptsMode)https://stackoverflow.com/questions/71968787
复制相似问题