在进行java代码的性能测试时,您需要测试JIT编译代码,而不是原始字节码。要使字节码被编译,必须通过多次执行代码来触发编译,并且还允许后台线程有足够的产生时间来完成编译。
我正在寻找可以安全应用于任何现代操作系统的门槛,比如Mac OS或Windows用于开发环境,Linux用于CI /生产。
答案 0 :(得分:13)
由于OP的意图实际上并未确定该块是否是JIT编译的,而是确保测量优化的代码,我认为OP需要观察some of these benchmarking talks。
TL; DR版本:没有可靠的方法来判断你是否达到了稳定状态":
您只能在很长一段时间内测量球场估计值,以确定您的具体系统达到某种状态所需的正常时间,并且可以声称“稳定”#。
观察-XX:+PrintCompilation
并不可靠,因为您可能处于计数器仍处于不稳定状态的阶段,JIT正等待编译下一批现在热门的方法。因此,你可以很容易地获得一些热身。该方法甚至可以多次重新编译,具体取决于分层编译器的数量。
虽然有人可能会争论调用阈值,但这些事情也不可靠,因为可能涉及分层编译,方法可能会更快地在调用者中内联,概率计数器可能会错过更新等等。这是关于-XX:CompileThreshold=#
的常识是不可靠的。
JIT编译不是您追求的唯一预热效果。自动GC启发式,调度程序启发式等也需要预热。
获取一个microbenchmark线束,让您更轻松地完成任务!
答案 1 :(得分:6)
首先,client or in server mode中的JVM运行结果很可能会有所不同。其次,这个数字在很大程度上取决于代码的复杂性,我担心你将不得不为每个测试用例进行探索性估计。通常,字节代码越复杂,可以对其应用的优化越多,因此您的代码必须相对更热才能使JVM深入到其工具箱中。 JVM可能会重新编译一段代码十几次。
此外,“真实世界”编译取决于运行字节代码的上下文。例如,当单态调用站点被提升为变形站点时,可能会发生编译,使得观察到的编译实际上代表 de - 优化。因此,在假设您的微型标记反映代码的实际性能时要小心。
我建议你使用CompilationMXBean
代替建议的标志,它允许你检查JVM在编译时仍然花费的时间。如果时间太长,请重新运行测试,直到值稳定足够长。 (请耐心等待!)框架可以帮助您创建良好的基准。就个人而言,我喜欢caliper。但是,永远不要相信你的基准。
根据我的经验,当您模仿 javac 的习语时,自定义字节代码的效果最佳。提到我可以讲述的一个轶事,我曾经为Java源代码编写了自定义字节代码,相当于:
int[] array = {1, 2, 3};
javac 创建数组并使用dup
来分配每个值,但我将数组引用存储在局部变量中,并将其加载回操作数堆栈以分配每个值。阵列的大小比那个大,并且有一个值得注意的性能差异。
最后,在编写基准之前,我建议this article。
答案 2 :(得分:4)
不确定数字,但在进行速度测试时,我所做的是:
-XX:-PrintCompilation
flag