Java微基准测试工具与System.getNanotime()的比较

4

问题1:为什么JMH比简单的System.getNanotime()更好?

问题2:除了validateLongKeyBinaryvalidateLongKeyAscii快64%,从基准测试结果部分我能得出什么结论?

示例(代码):

import net.spy.memcached.util.StringUtils;
import org.openjdk.jmh.annotations.GenerateMicroBenchmark;

public class KeyBench {

private static final String LONG_KEY = "thisIsAFunkyKeyWith_underscores_AndAlso334" +
            "3252545345NumberslthisIsAFunkyKeyWith_underscores_AndAlso3343252545345Numbe" +
            "rslthisIsAFunkyKeyWith_underscores_AndAlso3343252545345NumberslthisIsAFunkyK" +
            "eyWith_underscores_AndAlso3343252545345Numbersl";


    @GenerateMicroBenchmark
    public void validateLongKeyBinary() {
        StringUtils.validateKey(LONG_KEY, true);
    }

    @GenerateMicroBenchmark
    public void validateLongKeyAscii() {
        StringUtils.validateKey(LONG_KEY, false);
    }
}

基准测试结果

# Running: benchmarks.KeyBench.validateLongKeyAscii

Result : 393,667 ±(95%) 13,985 ±(99%) 20,094 ops/ms
  Statistics: (min, avg, max) = (357,445, 393,667, 413,004), stdev = 19,552
  Confidence intervals: 95% [379,682, 407,653], 99% [373,573, 413,762]


# Running: benchmarks.KeyBench.validateLongKeyBinary

Result : 644,023 ±(95%) 6,881 ±(99%) 9,887 ops/ms
  Statistics: (min, avg, max) = (621,784, 644,023, 654,178), stdev = 9,620
  Confidence intervals: 95% [637,142, 650,904], 99% [634,136, 653,910]

Benchmark                             Mode Thr     Count  Sec         Mean   Mean error    Units
b.KeyBench.validateLongKeyAscii      thrpt   1        10    1      393,667       20,094   ops/ms
b.KeyBench.validateLongKeyBinary     thrpt   1        10    1      644,023        9,887   ops/ms

3
相关问题:如何在Java中编写正确的微基准测试? - Luiggi Mendoza
1
不应该将 LONG_KEY 声明为静态常量,因为这可能会导致优化问题。只需使用 private String 即可。600k 次操作每毫秒相当于 0.6 次操作 / 纳秒,因此每个方法调用使用的 CPU 周期少于 5 个(取决于您的处理器)。这似乎有点太快了。 - assylias
尽管阅读这个问题的人已经知道:它是JMH(而不是JHM),关于http://openjdk.java.net/projects/code-tools/jmh/。 - Marco13
@LuiggiMendoza 谢谢,但是那个参考资料是关于如何编写微基准测试的。我想问的是,如果我们已经有了 System.getNanotime(),为什么我们还要编写微基准测试呢? - VB_
@assylias 谢谢。但是为什么我们应该使用微基准测试而不是简单的时间测量呢? - VB_
Luiggi提供的链接解释了微基准测试的所有陷阱。使用库可以避免这些陷阱(足够的JIT预热,将测量的内容放入方法中,避免循环展开等)。最终,这些库使用时间测量,因此您也可以手动执行-只是更难正确执行。 - assylias
1个回答

14

我是JMH维护者。

让我提出一个问题: 如果您可以自己编码完成大部分事情,为什么还要使用该库呢?答案实际上很简单:当然您可以在无限的时间内编写所有内容,但在实践中,我们必须重用代码以适应合理的时间。

现在,似乎只需要在代码周围拥有两个时间戳即可测量其性能。但是,您必须控制您正在测量的确切内容,例如您是否仍处于过渡热身阶段,您的代码实际执行或您在优化后测量一个空壳体,您的效果在统计学上的显著程度等等。好的基准测试框架试图帮助解决这些问题。

您可以通过查看JMH样例、我们的基准测试演讲或相关的SO答案来了解您将面临的问题。哦,使用nanoTime比您想象的更难


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接