Kotlin measureTime 与 kotlinx-benchmark (jmh) 有很大不同

Kotlin measureTime differs from kotlinx-benchmark (jmh) by far

我正在使用以下 class 进行测试(您可以找到 git 存储库 here):

@ExperimentalStdlibApi
@State(Scope.Benchmark)
class TestBenchmark {

    private fun benchmark() : List<Int> {
        return buildList {
            addAll(0..100)
            shuffle()
            sortDescending()
        }
    }

    final fun measureTime() {
        val result: Any?
        val time = measureNanoTime {
            result = benchmark()
        }
        println("$time ns")
    }

    @Benchmark
    @BenchmarkMode(Mode.SampleTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    final fun benchmarkFunction() {
        benchmark()
    }
}

@ExperimentalStdlibApi
fun main() {
    TestBenchmark().measureTime()
}

使用 kotlins measureTimeNanos 我在我的机器上得到了 65238400 ns。但是,当通过 gradlew benchmark 使用 kotlinx-benchmark 执行基准测试时,我得到:

  Success: N = 611869
  mean =  12388,465 ±(99.9%) 39,959 ns/op

这怎么可能?

您根本不能将 measureNanoTime 用于这样的微基准测试:该结果完全不可靠。一个很大的原因是 JVM 在运行时进行的优化,以及 GC 等非确定性行为或电源管理、OS 调度和时间共享等系统效应。

JMH 的全部意义在于创建一个试图解决所有这些问题的工具,以产生更可靠的微基准测试结果。

有关问题的更深入讨论,请参阅文章 Avoiding Benchmarking Pitfalls on the JVM

Aleksey Shipilëv 是 JMH 的维护者之一,有许多引人入胜的文章和关于该主题的讨论。参见:

另请参阅:How do I write a correct micro-benchmark in Java?