Java 内联
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1159087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Inlining in Java
提问by CL23
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.
在 C++ 中,我可以声明一个“内联”方法,编译器很可能会内联它。据我了解,Java 中没有这样的关键字。
Inlining is done if the JVM decides to do so? Can I influence this decision somehow?
如果 JVM 决定这样做,内联是否完成?我能以某种方式影响这个决定吗?
回答by Jon Skeet
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.
基本上让 JVM 完成它的工作——它可能比你更擅长确定在哪里内联。
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 hugedifference.
您是否遇到过确信 JVM 工作不佳的情况?假设您使用的是 HotSpot,您是否尝试过使用服务器版本而不是客户端?这可以产生巨大的差异。
回答by Shimi Bandiel
Although the java compiler can do inline (for short early-bound methods) the realinlining will be done by the JIT compiler. The JIT (HotSpot) compiler will be able to,even, inline virtualmethods. 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.
尽管 java 编译器可以进行内联(简称早期绑定方法),但真正的内联将由 JIT 编译器完成。JIT(HotSpot)编译器甚至能够内联虚拟方法。与其交互的最佳方式是编写简单简洁的代码。最有可能的是,使用反射的代码不允许内联。
Hope that helps.
希望有帮助。
回答by David Rodríguez - dribeas
'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.
'在 C++ 中,我可以声明一个方法“内联”,编译器会内联它'......或不。编译器可以自由地使函数内联或不内联,您不能真正影响结果。这只是对编译器的一个提示。
In Java there is no such thing, the compiler (and later the VM while performing optimizations) can decide to 'inline' the method.
在 Java 中没有这样的事情,编译器(以及稍后执行优化时的 VM)可以决定“内联”该方法。
Note that finalmethods 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.
请注意,final方法更有可能被内联(编译器无法内联非 final 方法,因为它们可能会在派生类中被覆盖)。使用现代 VM,可以在运行时进行类似的优化。VM 将标记类型(因此它可以执行类型检查)并将内联代码。只有当检查失败时,它才会回退到原始未优化的多态方法调用。
回答by PaulJWilliams
Inlining is more likely to happen if the method in question is:
如果所讨论的方法是:
- short
- final
- not dependent on any long, non final methods
- 短的
- 最后
- 不依赖于任何长的、非最终的方法
As these are the only circumstances where the JVM can be certain of the effects of the call.
因为这些是 JVM 可以确定调用效果的唯一情况。
回答by dfa
class A {
final int foo() { return 3; }
}
Given this class, any call to foo() can be replaced with the constant "3". Any Java1 virtual machine can do this, because the finalkeyword explicitly dictates that it isn't possible to have a subclass that overrides "int foo()".
给定这个类,任何对 foo() 的调用都可以替换为常量“3”。任何 Java1 虚拟机都可以这样做,因为final关键字明确规定不可能有一个覆盖“int foo()”的子类。
Inlining the method provides the following benefits at the call site:
内联该方法在调用站点提供以下好处:
- No method call
- No dynamic dispatch
- Possible to constant-fold the value, eg. "a.foo()+2" becomes 5 with no code executed at
runtime.
- 没有方法调用
- 没有动态调度
- 可以对值进行常量折叠,例如。"a.foo()+2" 变为 5,
运行时不执行任何代码。
In the past, programmers often inserted the finalkeyword 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.
过去,程序员经常正是因为这个原因才插入final关键字。或者为了更好地促进内联并提高执行速度,他们会将许多较小的方法组合成一个较大的方法。但在许多方面,此类技术破坏了编程语言中内置的模块化和可重用性的整个设施。
Modern JVM, like the Java HotSpot VM is able to inline the class without the final. keyword**.
现代 JVM,如 Java HotSpot VM 能够在没有最终. 关键词**。
(http://java.sun.com/developer/technicalArticles/Networking/HotSpot/inlining.html)
( http://java.sun.com/developer/technicalArticles/Networking/HotSpot/inlining.html)
回答by Mustafa Kemal
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.
在比较普通函数和最终函数(JVM 据说是内联的)时,我发现它们之间没有性能提升。也许函数调用的开销已经很低了。
Note: I used box blurring algorithm for evaluating performance.
注意:我使用框模糊算法来评估性能。
回答by Geek
Read this for Inlining behavior. http://www.javacoffeebreak.com/articles/thinkinginjava/comparingc++andjava.html
阅读此内容以了解内联行为。 http://www.javacoffeebreak.com/articles/thinkinginjava/comparingc++andjava.html
It says Final methods can be Inlined but not always.
它说最终方法可以内联,但并非总是如此。
回答by Yishai
Yes, if the JVM decides to do it, it can. Ways to influence include setting the method as static or as final.
是的,如果 JVM 决定这样做,它可以。影响的方法包括将方法设置为静态或最终。
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.
当然,最重要的是方法的结构需要内联友好。Short 有帮助,但最重要的是它只需要使用它的局部变量和它的参数,没有字段,并且对同一类中的其他方法的调用最少。
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 有时会意识到可以在没有这些提示的情况下内联方法。

