如何在Java中编写正确的微基准?

问题:

您如何在Java中编写(并运行)正确的微基准?
我正在寻找代码示例和评论,说明各种想法。
示例:基准测量时间/迭代或迭代/时间,为什么?
相关:Is stopwatch benchmarking acceptable?

回答:

关于撰写微量基准的提示from the creators of Java HotSpot
 规则0:阅读有关JVM和微型基准测试的声誉良好的论文。一个好的是Brian Goetz, 2005。不要指望微观基准太多;它们仅测量有限范围的JVM性能特征。
 规则1:始终包括一个预热阶段,运行测试内核一直通过,足以在定时阶段之前触发所有初始化和编译。 (在预热阶段,迭代次数越少越好,经验法则是数十万次内循环迭代。)
 规则2:始终使用-XX:+PrintCompilation-verbose:gc等运行,因此您可以在时序阶段验证编译器和JVM的其他部分是否没有出现意外的工作。
 规则2.1:在时序和预热阶段的开始和结束打印消息,因此您可以在时序阶段验证规则2中是否没有输出。
 规则3:请注意-client和-server之间的区别,OSR和常规编译之间的区别。 -XX:+PrintCompilation标志报告具有at符号的OSR编译以表示非初始入口点,例如:Trouble$1::run @ 2 (41 bytes)。喜欢服务器到客户端,并定期到OSR,如果你是最好的表现。
 规则4:注意初始化效果。在打印加载并初始化类时,请勿在时序阶段首次打印。除非您正在特别测试类加载(在这种情况下仅加载测试类),否则不要在预热阶段(或最终报告阶段)之外加载新类。规则2是你对抗这种效应的第一道防线。
 规则5:注意优化和重新编译效果。在定时阶段不要第一次采取任何代码路径,因为编译器可能会基于较早的乐观假设,即根本不会使用该路径,从而可以对代码进行垃圾和重新编译。规则2是你对抗这种效应的第一道防线。
 规则6:使用适当的工具来阅读编译器的头脑,并期望它产生的代码感到惊讶。在形成关于什么使事情更快或更慢的理论之前自己检查代码。
 规则7:减少测量中的噪音。在一台安静的机器上运行基准测试,并运行几次,抛弃异常值。使用-Xbatch使用应用程序序列化编译器,并考虑设置-XX:CICompilerCount=1以防止编译器自身并行运行。
 规则8:为您的基准使用库,因为它可能更有效率,并且已经为此唯一目的进行了调试。例如JMHCaliperBill and Paul’s Excellent UCSD Benchmarks for Java

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: How do I write a correct micro-benchmark in Java?

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

77 − = 72