我正在使用JMH来对DOM解析器进行基准测试。我得到了非常奇怪的结果,因为第一次迭代实际上比后来的迭代运行得更快
任何人都能解释为什么会这样吗?此外,百分位数和所有数字意味着什么以及为什么它在第三次迭代后开始变得稳定?一次迭代是否意味着整个基准测试方法的一次迭代?以下是我正在运行的方法
@Benchmark
@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 13, time = 1, timeUnit = TimeUnit.MILLISECONDS)
public void testMethod_no_attr() {
try {
File fXmlFile = new File("500000-6.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
} catch (Exception e) {
e.printStackTrace();
}
}
答案 0 :(得分:1)
您的屏幕截图缺少直方图输出。 你看到的只是一个percentile of the histogram。
检查此示例。我们有100次迭代,方法BoolArrayVsBitSetBenchmark#primitive的结果是:
Result "de.jawb.jmh.benchmark.example.bool.BoolArrayVsBitSetBenchmark.primitive":
N = 100
mean = 0,493 ±(99.9%) 0,003 s/op
Histogram, s/op:
[0,490, 0,495) = 93
[0,495, 0,500) = 3
[0,500, 0,505) = 1
[0,505, 0,510) = 1
[0,510, 0,515) = 0
[0,515, 0,520) = 0
[0,520, 0,525) = 1
[0,525, 0,530) = 0
[0,530, 0,535) = 0
[0,535, 0,540) = 0
[0,540, 0,545) = 0
[0,545, 0,550) = 0
[0,550, 0,555) = 0
[0,555, 0,560) = 1
Percentiles, s/op:
p(0,0000) = 0,490 s/op
p(50,0000) = 0,491 s/op
p(90,0000) = 0,494 s/op
p(95,0000) = 0,496 s/op
p(99,0000) = 0,558 s/op
p(99,9000) = 0,559 s/op
p(99,9900) = 0,559 s/op
p(99,9990) = 0,559 s/op
p(99,9999) = 0,559 s/op
p(100,0000) = 0,559 s/op
第一个直方图行[0,490, 0,495) = 93
表示93个调用属于 max 0,490s 和 min 0,494s 组。请注意括号')'
总之,这意味着没有调用速度更快,为0,491 s / op,因为
p(0,0000)= 0,490 s / op
max 执行时间为0,559 s / op,因为
p(100,0000)= 0,559 s / op
答案 1 :(得分:1)
这些百分位数非常具有误导性。不要使用它们。
如果您有N = 10
,难怪所有底部值都相同。
因为你有太少的样本来讨论像99.999%分位数这样的东西。我在这里实际考虑的唯一值是中位数(50%分位数),最终是IQR(四分位数比率)。
如果您乐观,您可以假设最慢的样本为95%。如果你不那么乐观,那么将N = 10的最慢样本视为90%分位数。如果你对这些估计更为认真,你可以将间距视为指示ca. 1 / sqrt(N-1),即假设高达33%的运行甚至比N=10
的最慢样本更慢。您需要更多样本来缩小这些估算值!任何超过95%的东西都只是猜测。 99% - 你无法回答那里发生的事情。你的数据不够。
如上所述,这些值完全是无意义的。根据数据,您无法估计P(99,9999)=某事。这个数字相当于百万分之一的运行比这更差。但是你只做了10次,不要用这个小N来预测如果你有一百万就会发生什么。 JMH不应该为小N打印这些极端分位数。