【IT168 评论】Java性能问题被冠以某种黑暗魔法的称谓。一部分是因为其平台的复杂性,在很多情况下,无法定位其性能问题根源。然而,在以前对于Java性能的技巧,有一种趋向:认为其由人们的智慧,经验构成,而不是应用统计和实证推理。在这篇文章中,我希望去验证一些最荒谬的技术神话。
1. Java运行慢
在所有最过时的Java性能谬论当中,这可能是最明显的言论。
是的,在90年代和20年代初期,Java确实有点慢。
然而,在那之后,我们有超过10年的时间来改进虚拟机和JIT技术,现在Java整个体系的性能已经快的令人惊讶。
在6个单独的web性能测试基准中,Java框架占据了24个当中的22个前四的位置。
JVM性能分析组件的使用不仅优化了通用的代码路径,而且在优化那些严重领域也很有成效。JIT编译代码的速度在大多数情况下跟C++一样快了。
尽管这样,关于Java运行慢的言论还是存在,估计是由于历史原因造成的偏见,这个偏见来自当时那些使用Java早期版本的人们。
我们建议,在匆忙下结论之前先保留意见和评估一下最新的性能结果。
2. 单行java代码意味着任何事都是孤立的
考虑以下一小段代码:
对一个Java开发者而言,很明显能看出这行代码需要分配一个对象和运行一个对应的构造方法。
从这来看,我们可以开始推出性能边界。我们知道有一些精确数量的工作必须继续,因此基于我们的推测,我们可以计算出性能影响。
这儿有个认知偏见,那就是根据以往的经验,任何工作都需要被做。
实际上,javac和JIT编译器都可以优化无效代码。就拿JIT编译器来说,代码甚至可以基于数据分析而被优化掉,在这种情况下,该行代码将不会被运行,因此它就不会有什么性能方面的影响。
而且,在一些Java虚拟机(JVM)中,例如JRockit中,即使代码路径没有完全失效,JIT编译器为了避免分配对象甚至可以执行分解对象操作。
这段文字在这里的意义就是当处理Java性能方面的问题时,上下文很重要。而且过早的优化可能会产生意料之外的结果。所以为了获得最好的结果,不要试图过早的优化。与其不断构建你的代码不如用性能调整技术去定位并且改正代码性能的潜在危险区。
3.你以为一个微基准测试代表了一切
正如前面所说,探讨一小段代码性能所得出的结果要比分析应用全局性能的结果要粗略的多。
虽说如此,但开发者们仍然喜欢写一些微基准测试。一些人追求通过改良平台底层某些方面而获得性能提升所带给他们的内在快乐,并乐此不疲。
Richard Feynman曾说过“第一原则就是不要自欺欺人,你就是那个最容易被糊弄的人”。现在,当你编写java微基准测试的时候,你真得好好想想这句话。
要想写出良好的微基准测试是很困难的。以深奥、复杂著称的Java平台为例,许多微基准测试仅能胜任测量瞬时效应或者一些平台无关的方面。
例如,一个未经过良好设计的微基准测试通常只注重测量耗时的子系统或垃圾回收的性能而忽略了在捕捉这些变化过程中所产生的开销。
只有当开发者和团队有真正基准需求的时候才需要写微基准测试。这些基准测试应该打包到项目(包括源代码)随项目一起发布,并且这些基准测试应该是可重现的并可提供给他人审阅和进一步的审查。
Java平台的许多优化结果都指的是只运行单一基准测试用例时所得到的统计结果。一个单独的基准测试必须要多次运行才能得到一个比较趋近于真实答案的结果。
如果你认为到了必须要写微基准测试的时候,首先请读一下Georges, Buytaert, Eeckhout所著的"Statistically Rigorous Java Performance Evaluation"。如果没有统计学的知识,你会很容易误入歧途的。
网上有很多好的工具和社区来帮助你进行基准测试,例如Google的Caliper。如果你不得不写基准测试时,不要埋头苦干,你需要从他人那里汲取意见和经验。