我有一个性能关键的代码片段,我想作为maven构建步骤保护,即JMH会运行并检查性能是否因本地更改而降低。
如何使用JMH检查此类降级?
我找到了一些相关的链接:
@Required()
注释)之前我已经实现了自动化性能测试(虽然不是使用Java,也不是在CI环境中)。需要注意的一个关键点是,您永远不会将其作为绝对运行,因为运行基准测试的计算机可能会有所不同。 BogoMips或依赖于测试的参考类型可用作相对比较。然后将基准测量为该参考时间的一些倍数,具有上限和下限。
虽然您通常对基准测试速度减慢(降级)持谨慎态度,但检查上限也很重要,因为它可能表示意外加速(更好的硬件支持),这应该表明需要检查系统/体系结构。
答案 0 :(得分:0)
JMH Maven插件不支持此功能。您必须编写自己的Maven插件才能执行此操作,否则您必须在构建生命周期中使用java exec插件来执行测试。您可以将基准测试结果写入文件,并找到另一个读取文件的Maven插件,如果它与给定的约束不匹配,则会破坏构建。
然而,我怀疑这是个好主意。如果您的代码更改显着改变了基准测试,那么您的基准测试可能不再适合您的代码。更糟糕的是,即使您的代码变慢,您的基准测试可能会变得更快,因为基准测试不再反映真实的用例。此外,你必须找到一个基线,因为基准不适合测量"绝对"运行时。
对于这种方法适当的地方可能存在一些极端情况,但您应该考虑是否真的值得这么麻烦。
答案 1 :(得分:0)
看起来有可能,这netty.io commit增加了对Junit Test中包含的JMH的支持。
我注意到JMH选项:
-rf <type> Result format type.
See the list of available result formats first.
-rff <filename> Write results to given file.
意思是我可以告诉Benchmark将其结果输出到JSON文件,然后我可以将其作为Junit运行的一部分进行解析。
最后一部分是将Run与Junit中的其他东西进行比较,也许是SPECjvm2008?
答案 2 :(得分:0)
我建议您通过Runner
简单地构建一组OptionsBuilder
选项,并在Junit测试中调用run
。
虽然一些作者建议不要在“干净”的环境中运行基准测试,但我认为这些效果非常微不足道,并且在与同一环境中的参考运行进行比较时可能无关紧要。
有关手动设置Runner
的最简单示例,请参阅here。
Runner.run()
(或者在单个基准Runner.runSingle()
的情况下)将返回Collection<RunResult>
或仅RunResult
,可以对其进行断言。
为了做到这一点,你可以简单地使用Statistics
(参见文档here),你可以从RunResult
通过RunResult.getPrimaryResult().getStatistics()
提取并对数值进行断言可以从Statistics
...或使用isDifferent()
方法,您可以选择在置信区间内比较两个基准运行(可能有助于自动捕捉两个方向的异常值)。