javac或Hotspot自动添加'final'作为不变变量的优化?
共识似乎是,将成员变量标记为最终变量会带来性能优势,因为它们永远不需要从主内存重新加载。我的问题是,当变量明显无法更改时,javac 或 Hotspot 会自动为我执行此操作吗?例如,javac 是否会将下面这个类中的“x”设为final...
public class MyClass {
private String x;
MyClass(String x) {
this.x = x;
}
public String getX() {
return x;
}
}
第二点,是否有人提供了经验证据,表明将成员标记为final 可以使代码运行得更快?在任何进行远程调用或数据库查找的应用程序中,任何好处肯定可以忽略不计吗?
The consensus seems to be that there is a performance benefit to marking member variables as final because they never need reloading from main memory. My question is, do javac or Hotspot automatically do this for me when it's obvious the variable cannot change. eg will javac make 'x' final in this class below...
public class MyClass {
private String x;
MyClass(String x) {
this.x = x;
}
public String getX() {
return x;
}
}
On a secondary point, has anyone produced empirical evidence that marking members as final makes code run faster? Any benefit is surely negligible in any application making remote calls or database lookups?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
与许多性能“增强”一样,通常最好询问;什么更容易理解和推理?例如,如果一个字段是最终的,我知道它不会在任何地方改变。这通常会产生更优化的代码,但更重要的是它应该是更易于维护的代码。 ;)
当然,我将任何可以最终确定的领域定为最终的。就我个人而言,我更希望
final
成为默认行为,并且您必须使用var
这样的关键字来使其可变。Like many performance "enhancements" it is usually a better to ask; What is easier to understand and reason about? e.g. if a field is final I know it won't be changed anywhere. This is often leads to more optimial code, but more importantly it should be more maintainable code. ;)
Certainly, I make any field which can be final as final. Personally I would have preferred that
final
be the default behaviour and you had to use a keyword likevar
to make it mutable.允许 javac 执行此操作将是一个错误。由于不同 jar 中可能存在依赖于正在编译的代码(模块化)的代码,因此在编译时更改代码以进行优化并不是一个可行的选择。
至于第二个参数“永远不需要从主内存重新加载”,需要记住大多数实例变量都被缓存了。 final 仅表示不变性,它不保证易变性(易失性==总是从主内存获取最新的)。因此在多线程环境中需要锁和 volatile 关键字。
至于热点的情况,我没有任何线索,想了解更多。 final 常量可以在编译时内联,从而实现适度的性能提升。参考in-lined in java的问题
编辑:
Note that final indicates immutability needs to be taken with a grain of salt. It does not guarantee that the state cannot change, it only specifies that the object reference can be modified. final indicates immutability for primitive data types
Allowing javac to do this would be a blunder. As there might be code in a different jar which may rely on the code being compiled (modularity), changing code at compile time for optimization sake is not a feasible option.
As for the second argument "never need reloading from the main memory", one needs to remember that most instance variables are cached. final only indicates immutability, it does not guarantee volatility (volatile == always get latest from main memory). Hence the need for locks and volatile keyword in multi-threaded environment.
As for the case with hotspot, I have no clue, and would like to hear more about it. final constants may be in-lined at compile time, thus allowing moderate performance gains. Reference to a question on in-lining in java
Edit:
Note that final indicates immutability needs to be taken with a grain of salt. It does not guarantee that the state cannot change, it only specifies that the object reference can be modified. final indicates immutability for primitive data types
AFAIK,他们没有,因此,你会受到轻微的惩罚。不过,这可以通过 IDE 工具自动完成,例如 Eclipse 的“清理”功能。
AFAIK, they do not, and thus, you suffer minor penalty. This, however, can be done automatically with IDE tools like Eclipse "Cleanup" feauture.
我相信现代 JVM(热点编译器)确实检测到该值没有改变,因此将参数或变量设置为final<代码不会带来性能优势/code> 你自己。 (如果这是错误的,请提供链接或测试用例。)有一个例外:常量(
static final
)。但是,这对于最终方法和类可能有所不同。在这种情况下它可能会提高性能(我不完全确定在什么情况下)。顺便说一句,使函数静态化(如果可能的话)可以稍微提高性能。
我对
final
的问题是它使代码变得混乱。如果 Final 是默认值,那就太好了。I believe a modern JVM (the Hotspot compiler) does detect that the value doesn't change, so there is no performance benefit in making parameters or variables
final
yourself. (If this is wrong, please provide a link or test case.) There is one exception: constants (static final
).However, this may be different with final methods and classes. It may improve performance in this case (I'm not completely sure in what cases). By the way, what does improve performance a little bit is making functions static (if possible).
The problem I have with
final
is that it clutters the code. It would be nice if final would be the default.