JMH - 奇怪的基准测试结果
JMH - weird benchmarking results
我正在使用 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();
}
}
您的屏幕截图缺少直方图输出。
你看到的只是一个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。注意括号')'
总而言之,这意味着 no 调用比 0,491 s/op 更快,因为
p(0,0000) = 0,490 s/op
而max执行时间为0,559s/op,因为
p(100,0000) = 0,559 s/op
这些百分位数具有可怕的误导性。不要使用它们。
如果你有N = 10
,难怪所有底值都一样。
因为你的样本太少,无法谈论 99.999% 的分位数。我在这里实际考虑的唯一值是中位数(50% 分位数),最后是 IQR (inter-quartile-ratio)。
如果您乐观,您会假设最慢的样本为 95%。如果不太乐观,则将 N=10 的最慢样本视为 90% 分位数。如果您对这些估计更认真,您可能会将间距视为 ca 的指示。 1/sqrt(N-1),即假设多达 33% 的运行将比 N=10
的最慢样本还要慢。您需要更多样本来缩小这些估计范围!任何超过 95% 的东西都只是猜测。 99% - 你无法回答那里发生的事情。你只是没有足够的数据。
如上所示,这些值完全是胡说八道。 根据数据,您无法估计 P(99,9999)= 某物。这个数字相当于百万分之一的运行比这更糟糕。但是你只做了 10 次,不要用这个小 N 来预测如果你有 100 万会发生什么。 JMH 不应为小 N 打印这些极端分位数。
我正在使用 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();
}
}
您的屏幕截图缺少直方图输出。 你看到的只是一个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。注意括号')'
总而言之,这意味着 no 调用比 0,491 s/op 更快,因为
p(0,0000) = 0,490 s/op
而max执行时间为0,559s/op,因为
p(100,0000) = 0,559 s/op
这些百分位数具有可怕的误导性。不要使用它们。
如果你有N = 10
,难怪所有底值都一样。
因为你的样本太少,无法谈论 99.999% 的分位数。我在这里实际考虑的唯一值是中位数(50% 分位数),最后是 IQR (inter-quartile-ratio)。
如果您乐观,您会假设最慢的样本为 95%。如果不太乐观,则将 N=10 的最慢样本视为 90% 分位数。如果您对这些估计更认真,您可能会将间距视为 ca 的指示。 1/sqrt(N-1),即假设多达 33% 的运行将比 N=10
的最慢样本还要慢。您需要更多样本来缩小这些估计范围!任何超过 95% 的东西都只是猜测。 99% - 你无法回答那里发生的事情。你只是没有足够的数据。
如上所示,这些值完全是胡说八道。 根据数据,您无法估计 P(99,9999)= 某物。这个数字相当于百万分之一的运行比这更糟糕。但是你只做了 10 次,不要用这个小 N 来预测如果你有 100 万会发生什么。 JMH 不应为小 N 打印这些极端分位数。