Java 中的内联
在 C++ 中,我可以声明一个“内联”方法,并且编译器可能会内联它。 据我了解,Java中没有这样的关键字。
如果 JVM 决定这样做,内联就会完成吗? 我可以以某种方式影响这个决定吗?
In C++ I can declare a method "inline" and the compiler is likely to inline it. As far as I understand there is no such keyword in Java.
Inlining is done if the JVM decides to do so? Can I influence this decision somehow?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
给定此类,对 foo() 的任何调用都可以替换为常量“3”。 任何 Java1 虚拟机都可以执行此操作,因为 final 关键字明确指示不可能有重写“int foo()”的子类。
内联方法在调用站点提供以下好处:
处执行
运行。
过去,程序员常常出于这个原因插入 final 关键字。 或者为了更好地促进内联并提高执行速度,他们会将许多较小的方法合并为一个较大的方法。 但在很多方面,这些技术都击败了编程语言中内置的模块化和可重用性的整个功能。
现代 JVM(例如 Java HotSpot VM)能够在没有 final 的情况下内联类。 关键词**。
(http://java.sun.com/developer/technicalArticles/Networking /HotSpot/inlined.html)
Given this class, any call to foo() can be replaced with the constant "3". Any Java1 virtual machine can do this, because the final keyword explicitly dictates that it isn't possible to have a subclass that overrides "int foo()".
Inlining the method provides the following benefits at the call site:
runtime.
In the past, programmers often inserted the final keyword for exactly this reason. Or to better facilitate inlining and increase execution speed, they would combine many smaller methods into one larger method. But in many ways, such techniques defeat the entire facility of modularization and reusability built into the programming language.
Modern JVM, like the Java HotSpot VM is able to inline the class without the final. keyword**.
(http://java.sun.com/developer/technicalArticles/Networking/HotSpot/inlining.html)
阅读本文了解内联行为。
http://www.javacoffeebreak.com/articles/thinkinginjava/comparingc++ andjava.html
它说 Final 方法可以内联,但并非总是如此。
Read this for Inlining behavior.
http://www.javacoffeebreak.com/articles/thinkinginjava/comparingc++andjava.html
It says Final methods can be Inlined but not always.
是的,如果 JVM 决定这样做,它就可以。 影响方法包括将方法设置为静态或最终方法。
当然,最重要的是方法的结构需要内联友好。 简短有帮助,但最重要的是,它只需要使用其局部变量及其参数,不需要字段,并且对同一类中的其他方法进行最少的方法调用。
然而,您不应该过早地进行此类优化,实际上可能会使事情变得更糟(因为您可能会短路其他潜在的优化)。 JVM 有时会意识到无需这些提示即可内联方法。
Yes, if the JVM decides to do it, it can. Ways to influence include setting the method as static or as final.
Of course, the most important thing about it is that the structure of the method needs to be inline friendly. Short helps, but most importantly it needs to only use its local variables and its parameters, no fields, and minimal method calls to other methods in the same class.
However you should not look to do such optimizations prematurely, you could actually be making things worse (because you could be short-circuiting other potential optimizations). The JVM will sometimes realize that a method can be inlined without these hints.
当比较普通函数和最终函数(据说是由 JVM 内联)时,我发现它们之间没有性能改进。 也许函数调用的开销已经很低了。
注意:我使用框模糊算法来评估性能。
When comparing a normal function and final function(which is said to be inline by JVM), I have seen that there is no performance improvement between them. Maybe overhead of function call is already very low.
Note: I used box blurring algorithm for evaluating performance.
其他几个答案表明只有最终方法可以内联 - 这不是真的,因为 HotSpot 足够聪明,只要它们还没有被覆盖,就能够内联非最终方法。 当加载覆盖该方法的类时,它可以撤消其优化。 显然,使该方法成为最终方法意味着永远不需要...
基本上让 JVM 完成其工作 - 它可能比您更好地确定内联位置。
您是否遇到过确信 JVM 表现不佳的情况? 假设您正在使用 HotSpot,您是否尝试过使用服务器版本而不是客户端? 这可以产生巨大的差异。
A couple of the other answers have suggested that only final methods can be inlined - this is not true, as HotSpot is smart enough to be able to inline non-final methods so long as they haven't been overridden yet. When a class is loaded which overrides the method, it can undo its optimisation. Obviously making the method final mean that's never required...
Basically let the JVM do its job - it's likely to be a lot better at working out where to inline than you are.
Do you have a situation where you're convinced that the JVM isn't doing a good job? Assuming you're using HotSpot, have you tried using the server version instead of client? That can make a huge difference.
尽管 java 编译器可以进行内联(简称早期绑定方法),但真正的内联将由 JIT 编译器完成。
JIT(HotSpot)编译器甚至能够内联虚拟方法。
与之交互的最好方法是编写简单简洁的代码。
最有可能的是,使用反射的代码不允许内联。
希望有帮助。
Although the java compiler can do inline (for short early-bound methods) the real inlining will be done by the JIT compiler.
The JIT (HotSpot) compiler will be able to,even, inline virtual methods.
The best way to interact with it is to write a simple and concise code.
Most likely, code that uses Reflection will not allow for inlining.
Hope that helps.
“在 C++ 中,我可以声明一个“内联”方法,编译器将内联它”...或不。 编译器可以自由地使函数内联或不内联,并且您不能真正影响结果。 它只是对编译器的一个提示。
在Java中没有这样的事情,编译器(以及后来执行优化时的VM)可以决定“内联”该方法。
请注意,final 方法被内联的机会更大(编译器无法内联非 Final 方法,因为它们可能会在派生类中被覆盖)。 使用现代虚拟机,可以在运行时进行类似的优化。 虚拟机将标记类型(以便它可以执行类型检查)并内联代码。 只有当检查失败时,才会回落到原来未优化的多态方法调用中。
'In C++ I can declare a method "inline" and the compiler will inline it'... or not. The compiler is free to make the function inline or not and you cannot really affect the result. It is only a hint to the compiler.
In Java there is no such thing, the compiler (and later the VM while performing optimizations) can decide to 'inline' the method.
Note that final methods have greater chances of being inlined (the compiler cannot inline non-final methods, as they may be overwritten in derived classes). With modern VM, a similar optimization can be made at runtime. The VM will flag the type (so it can perform type checks) and will inline the code. Only if the check fails, it will fall back into the original unoptimized polymorphic method call.
更有可能发生内联,
因为这是JVM 可以确定调用效果的唯一情况。
Inlining is more likely to happen if the method in question is:
As these are the only circumstances where the JVM can be certain of the effects of the call.