Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JMH如何测量粒度值以下的执行时间?_Java_Jmh - Fatal编程技术网

Java JMH如何测量粒度值以下的执行时间?

Java JMH如何测量粒度值以下的执行时间?,java,jmh,Java,Jmh,所以我试着玩一下微基准,选择了JMH,读了一些文章JMH如何在系统计时器粒度以下度量方法的执行? 更详细的解释是: 以下是我正在运行的基准测试(方法名称不言而喻): 以下是结果: # Run complete. Total time: 00:00:02 Benchmark Mode Cnt Score Error Units RandomBenchmark.blankMethod avgt 20 0,88

所以我试着玩一下微基准,选择了JMH,读了一些文章JMH如何在系统计时器粒度以下度量方法的执行?

更详细的解释是:

以下是我正在运行的基准测试(方法名称不言而喻):

以下是结果:

# Run complete. Total time: 00:00:02

Benchmark                          Mode  Cnt    Score    Error  Units
RandomBenchmark.blankMethod        avgt   20    0,887 ?  0,274  ns/op
RandomBenchmark.granularityMethod  avgt   20  407,002 ? 26,297  ns/op
RandomBenchmark.simpleMethod       avgt   20    6,979 ?  0,743  ns/op
目前运行在Windows7上,正如各种文章中所描述的,它的粒度很大(407ns)。使用下面的基本代码进行检查,每隔400ns就会出现一个新的计时器值:

    final int sampleSize = 100;
    long[] timeMarks = new long[sampleSize];
    for (int i=0; i < sampleSize; i++) {
        timeMarks[i] = System.nanoTime();
    }
    for (long timeMark : timeMarks) {
        System.out.println(timeMark);
    }
final int sampleSize=100;
long[]timeMarks=新的long[sampleSize];
for(int i=0;i

很难完全理解生成的方法到底是如何工作的,但通过查看反编译的JMH生成的代码,它似乎在执行前后使用了相同的System.nanoTime(),并测量了差异。当粒度为400纳秒时,它如何能够测量几个纳秒的方法执行呢?

你完全正确。您无法测量比系统计时器粒度更快的内容

JMH不会度量bechmark方法的每次调用。它在迭代开始前调用System.nanotime(),执行基准方法X次,并在迭代后再次调用System.nanotime()。然后,结果是操作的时差/#(您可能会在方法上使用@OperationsPerinviation在每次调用中指定多于1个操作)


Aleksey Shipilev在他的文章中讨论了纳米时间的测量问题。“延迟”部分包含一个代码示例,显示JMH如何度量一个基准迭代

如果它没有足够多次地迭代测量的方法,那么你就明白了。可能是通过对多个样本进行平均?是的,这是一个明显的想法,但考虑到nanoTime()是固有的,可能还有其他一些技巧。Shipilev的博客也可能对你有用:。观看一些演示,了解更多关于JMH的信息,以及在创建一个好的基准时将面临的问题。
    final int sampleSize = 100;
    long[] timeMarks = new long[sampleSize];
    for (int i=0; i < sampleSize; i++) {
        timeMarks[i] = System.nanoTime();
    }
    for (long timeMark : timeMarks) {
        System.out.println(timeMark);
    }