Java JMH多个基准测试在独立运行上的不同结果
我通过JMH运行了一些基准测试 假设我在一个Java文件中列出了三个基准测试Java JMH多个基准测试在独立运行上的不同结果,java,benchmarking,jmh,Java,Benchmarking,Jmh,我通过JMH运行了一些基准测试 假设我在一个Java文件中列出了三个基准测试 @Benchmark @Threads(value = 2) @Warmup(iterations = 10) @Fork(value = 2) @Measurement(iterations = 10) public String benchmarkA() { ... } @Benchmark @Threads(value =
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkA() {
...
}
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkB() {
...
}
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkC() {
...
}
每种方法都对不同的算法进行基准测试,以达到相同的目的。当我一起运行所有基准测试时,与逐个运行基准测试相比,结果会有所不同
例如,在Java文件上仅使用onw基准执行JMH运行
@Benchmark
@Threads(value = 2)
@Warmup(iterations = 10)
@Fork(value = 2)
@Measurement(iterations = 10)
public String benchmarkA() {
...
}
如果只运行此方法,此方法的结果会更好,但是如果使用更多基准,结果会更差
假设通过单独运行它们,结果方面的benchmarkA>benchmarkB>benchmarkC,如果我一次性运行它们,它们之间的差异会放大
我还尝试改变基准测试的顺序(按字典顺序执行),结果是一样的。就好像基准的数量会影响结果一样
原因可能是什么?每个基准都在自己的JVM中执行(除非明确设置为其他方式),所以不应该发生跨基准污染。可能发生的,并且是很常见的,是CPU的热节流。如果您在一个无法控制CPU频率的环境中进行基准测试,典型的行为将是第一个基准测试将CPU频率推高,而随后的基准测试将受到限制。在Linux环境中,您可以通过切换到用户控制的电源调节器并为CPU设置固定频率来控制此变量。如果所有算法都是内存密集型的,则在内存消耗达到GC限制和第二/第三次执行GC hit之前,第一次完成。基准测试与它们自己的JVM隔离,所以不应该影响以下基准的GC。我将此标记为一个答案,因为这是目前我能看到的唯一原因。的确,这个操作需要大量的cpu。我以前听说过,但它相当可怕。这意味着在一个典型的jmh设置中,基准的顺序可能很重要?