Java JMH如何测量粒度值以下的执行时间?
所以我试着玩一下微基准,选择了JMH,读了一些文章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
# 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);
}