为val和case class使用final关键字是否存在额外性能收益?
final关键字除了防止重写之外的性能收益
答案是肯定有明确的性能收益,主要来自JVM运行时优化和Scala编译期优化两个层面:
- JIT内联优化:JVM的即时编译器默认会对不能被重写的非虚方法执行激进的内联操作,直接消除方法调用的开销。没有加
final的val对应的getter方法是可以被子类重写的虚方法,JIT只有通过逃逸分析确定实例实际类型的前提下才会尝试内联;而加了final的val的getter方法属于非虚方法,JIT可以直接内联,热点代码路径下性能提升非常明显。 - case class专属优化:Scala 2版本中没有加
final的case class允许被普通类继承,自动生成的copy、equals、hashCode、productElement等方法都属于虚方法,加了final之后这些方法都变成非虚方法,同样可以被JIT内联,同时序列化、模式匹配的逻辑也可以省去子类兼容的判断分支,执行速度更快。 - 编译期常量折叠:如果加了
final的val赋值的是字面量或者可在编译期计算的常量表达式,Scala编译器会直接执行常量折叠,把所有引用这个val的位置直接替换成常量值,完全省去运行时的取值开销。
注意:以上性能收益只在高并发核心逻辑、循环内高频调用等热点路径下感知明显,非热点代码不需要为了性能强行添加
final,优先保证代码可维护性即可。
内容的提问来源于stack exchange,提问作者FrancMo
相关产品推荐
相关产品推荐

