【IT168 技术】Java的性能有某种黑魔法之称。部分原因在于Java平台非常复杂,很多情况下问题难以定位。然而在历史上还有一种趋势,人们靠智慧和经验来研究Java性能,而不是靠应用统计和实证推理。在这篇文章中,我希望拆穿一些最荒谬的技术神话。
1.Java很慢
关于Java的性能有很多谬论,这一条是最过时的,可能也是最为明显的。
确实,在上世纪90年代和本世纪初处,Java有时是很慢。
然而从那以后,虚拟机和JIT技术已经有了十多年的改进,Java的整体性能现在已经非常好了。
在6个独立的Web性能基准测试中,Java框架在24项测试中有22项位列前四。
尽管JVM利用性能剖析仅优化常用的代码路径,但这种优化效果很明显。很多情况下,JIT编译的Java代码和C++一样快,而且这样的情况越来越多了。
尽管如此,依然有人认为Java平台很慢,这或许源自体验过Java平台早期版本的人的历史偏见。
在下结论之前,我们建议保持客观的态度,并且评估一下最新的性能结果。
2.可以孤立地看待单行Java代码
考虑下面这行短小的代码:
对Java开发者而言,看似很明显,这行代码一定会分配一个对象并调用适当的构造器。
我们也许可以据此推出性能边界了。我们认为这行代码一定会导致执行一定量的工作,基于这种推定,就可以尝试计算其性能影响了。
其实这种认识是错误的,它让我们先入为主地认为,不管什么工作,在任何情况下都会进行。
事实上,javac和JIT编译器都能够将死代码优化掉。就JIT编译器而言,基于性能剖析数据,甚至可以通过预测将代码优化掉。在这样的情况下,这行代码根本不会运行,所以不会影响性能。
此外,在某些JVM中——比如JRockit——JIT编译器甚至可以将对象上的操作分解,这样即便代码路径还有效,分配操作也可以避免。
这里的寓意是,在处理Java性能问题时,上下文非常重要,过早的优化有可能产生违反直觉的结果。所以最好不好过早优化。相反,应该总是构建代码,并且使用性能调校技术来定位性能热点,然后加以改进。
3.微基准测试和你想象的一样
正如我们上面看到的那样,检查一小段代码不如分析应用的整体性能来的准确。
尽管如此,开发者还是喜欢编写微基准测试。似乎对平台底层的某些方面进行修修补补会带来无穷的乐趣。
理查德·费曼曾经说过:“不要欺骗自己,你自己正是最容易被欺骗的人。”这句话用来说明编写Java微基准测试这件事是再合适不过了。
编写良好的微基准测试极其困难。Java平台非常复杂,而且很多微基准测试只能用于测量瞬时效应,或是Java平台的其他意想不到的方面。
例如,如果没有经验,编写的微基准测试往往就是测一下时间或垃圾收集,却没有抓住真正的影响因素。
只有那些有实际需求的开发者和开发团队才应该编写微基准测试。这些基准测试应该完全公开(包括源代码),而且是可以复现的,还应接受同行评审及进一步的审查。
Java平台的很多优化表明统计运行和单次运行对结果影响很大。要得到真实可靠的答案,应该将一个单独的基准测试运行多次,然后把结果汇总到一起。
如果读者感觉有必要编写微基准测试,Georges、Buytaert和Eeckhout等人的论文《利用严格的统计方法评测Java 性能(Statistically Rigorous Java Performance Evaluation)》是个不错的开始。缺乏适当的统计分析,我们很容易被误导。
有很多开发好的工具以及围绕这些工具的社区(比如Google的Caliper)。如果确实有必要编写微基准测试,那也不要自己编写,这时需要的是同行的意见和经验。