三种提升Java代码性能的简单技巧 - levelup


优先考虑组成而不是继承、尽一切可能内联方法、创建小方法是简单的提升代码性能方法:
大多数开发人员会遇到有关Java性能的问题。大多数开发人员不知道正确的答案。这里提供三种简单优化技巧:
 
1.内联Java
内联方法是JIT编译器使用的一种优化技术。研究表明,其加速比高达93倍。
哪些方法易于内联?静态,私有,最终final方法很容易内联;虚拟调用如果是monomorphic单态调用,则可以内联。方法调用默认是虚拟的,这意味着您需要搜索vtable以获得方法引用,通过一种多态性,您可以为一个方法拥有多个调用入口。
可以内联哪些方法?公开public方法,但必须满足一些标准方法。方法大小是一项标准。在Linux 64位上,将大小定为325字节以下的方法可以内联。小型方法可以内联,而大型方法则不能。
JIT编译器如何优化单态调用?使用内联缓存。默认情况下,只有单态调用。发生子类调用时,它会分支为megamorphic巨形调用。
什么是巨形调用?子类中的重写方法会导致巨形调用。调用vtable,就不会产生包含所有可能的方法调用的表。
内联可以为您做什么?为什么单态调用比多态调用更好?让我们来看看:我们可以使用此基准测试方法的大小优化。为了测试方法调用的内联缓存,我们可以使用这里的基准。
不能内联哪些方法?
如何搜索未优化的方法?使用jarScan限制为325个字节。该限制可能因平台而异。此限制是大方法的指标。这是一个大方法的示例。

./jarScan.sh --mode=maxMethodSize --limit=325 ./yourproject.jar
"com.yourproject","HugeClass","com.yourproject.HugeClass$Builder",637

 
2.组合如何击败继承
Bimorphic双态调用在行内缓存中获得匹配。我们可以看到,双态使操作次数提高了35%。
做简单instanceof可以改善内联缓存中的点击率。优化使吞吐量提高了30%。
是什么使巨形调用的执行效果不佳?在线缓存中未命中。转到vtable。遍历vtable会降低执行速度。
这是多态性的主要问题:
像Java这样的编程语言提供了多态的便利,作为构造模块化和可重用软件的方法之一。这种语言选择自然是有代价的,因为没有硬件支持虚拟调用,因此运行时必须模仿这种行为。— AlekseyShipilёv
单态的性能比双态的性能高4倍。
通过基准测速表明:内联方法的性能更好。多态方法的性能比单态方法差。
我们可以了解到为什么合成胜过继承。继承为vtable带来了更多方法,从而导致性能瓶颈。力争使用较小的方法,这些方法可以内联并表现更好。
 
 

3.小方法快大方法慢?
让我们从一开始就尝试我们的基准测试。较小的方法的性能要好26倍。如果我们不内联较小的方法怎么办?内联方法如何影响平均时间?内联方法的性能比同类方法好2倍。
我们可以从这些基准中学到什么?尽一切可能使您的方法内联。创建较小的方法,并减少项目中现有的较大方法。吞吐量性能取决于大小。小型内联方法平均快2倍。