以下是代码段:
https://gist.github.com/987751
对我而言,时间就像:
java -client: for loop took: 23 method call took: 19 java -server: for loop took: 0 # faster, as expected method call took: 48 # slower--expected?
所以第一个问题是“为什么它比客户端VM慢”
另外我猜下一个问题是“是否有可能为方法调用方式获得超级0ms的加速(这几乎是相同的代码)?”
此外,我认为尽管存在这种奇怪现象,但一般情况下,热点运行速度要快得多,即使是匿名课程也是如此?
谢谢!
-roger -
答案 0 :(得分:2)
关于如何调整热点的两种风格:
客户端已经过调整以便快速启动。 JIT直接“几乎”编译方法。
服务器在假定为长调优服务器实例的生命周期内针对高(er)吞吐量进行调整。它允许解释器在JIT编译之前运行方法更长(收集使用统计信息)。然后(我相信)它执行更积极的优化......这需要更长的时间。
相关答案:Real differences between "java -server" and "java -client"?
顺便说一句,它是运行客户端和服务器模式的相同Hotspot JVM。 AFAIK,差异是由于两种模式选择不同的默认JVM调整/配置参数。
所以第一个问题是“为什么它比客户端VM慢”
我不知道。
也许客户端模式可以实现特定的优化,真正有助于这种(高度人为的)基准测试。或许服务器模式优化之一实际上是对这种(高度人为的)基准测试的反优化。如果您真的想知道,请让JIT编译器转储本机代码并详细分析它。 (但我认为这是浪费时间。)
另外我猜下一个问题是“是否有可能为方法调用方式获得超级0ms的加速(这几乎是相同的代码)?”
这很容易。优化器已经发现方法调用不会影响其他任何东西,并且已经优化了调用。然后也可以优化循环。
此外,我认为尽管存在这种奇怪现象,但一般情况下,热点运行速度要快得多,即使是匿名课程也是如此?
我认为你不应该假设任何东西。
但是,我也不认为您的微基准测试对真实程序有任何意义。微基准测试通常会产生误导,而你的测试结果存在缺陷(例如,被优化掉的循环)并且似乎没有测试典型(编写良好)的Java程序会做的事情。
如果您真的关心两种HotSpot模式的相对性能,您应该运行并测量应用程序在实际数据上的性能。
...为什么服务器JVM会选择看似更糟糕的东西?
优化器旨在优化真正的程序......而不是微观基准,它们花费时间做一些与有用计算没有任何相似之处的奇怪事情。并非所有优化都适用于所有情况,并且您可能遇到了某种边缘情况。
但只有在实际应用中发现同样的事情时,这才有意义。
最后,您不会提供有关JVM版本,平台和硬件的任何详细信息。这些事情可能会对相对绩效指标产生巨大影响。