[英]Scope of temporary variables — does Eclipse/compiler optimize?
First of all, I ask those with "premature optimization" phobia to spare me: I don't want to optimize anything, I'm just curious . 首先,我要求那些“过早优化”恐惧症的人免除我:我不想优化任何东西,我只是好奇 。
I read/observed two things, including on stackoverflow (can't find the link now): 我阅读/观察了两件事,包括在stackoverflow上(现在找不到链接):
I'm wondering what the compiler/JIT/whatever can actually optimize, and what it can't. 我想知道编译器/ JIT /什么可以实际优化,什么不能。
Here is the following method (assume that the variables are actually used , so they can't be optimized away for that reason): 以下是以下方法(假设实际使用了变量,因此无法对其进行优化):
// The method does many (useful) things, but these were cut here
public void myMethod() {
int var1 = 1;
... // do work
if (something) {
int var2 = 2;
int var3 = 3;
... // do work
}
int var4 = 4;
int var5 = 5;
... // do work
}
1.) Is the compiler able to detect that the space for var2
and var3
can be reused for var4
and var5
? 1.)编译器是否能够检测到
var2
和var3
的空间可以重用于var4
和var5
? I don't remember seeing such a thing in disassembled bytecodes. 我不记得在反汇编的字节码中看到过这样的事情。
2.) Is the code method above equivalent to the case when the end of the method is put to {} too? 2.)上面的代码方法是否等同于将方法的结尾放到{}的情况?
public void myMethod() {
int var1 = 1;
... // do work
if (something) {
int var2 = 2;
int var3 = 3;
... // do work
}
{
int var4 = 4;
int var5 = 5;
... // do work
}
}
Finally, let's see a simpler case: 最后,让我们看一个更简单的案例:
public void myMethod() {
int var1 = 1;
... // do work, and then don't refer to var1 any more
int var4 = 4;
int var5 = 5;
... // do work
}
3.) In this case, can var1
memory be reused for var4
(or var5
)? 3.)在这种情况下,可以为
var4
(或var5
)重用var1
内存吗? Ie in such a case, it is enough for the method to have memory for two local int
variables, not for three. 即在这种情况下,该方法足以为两个本地
int
变量提供内存,而不是三个。
(I know that in theory, these are obvious cases for the compiler, but sometimes I overlook things eg why a compiler can't do or assume anything.) (我知道理论上,这些是编译器的明显案例,但有时我会忽略一些事情,例如为什么编译器不能做或假设任何事情。)
I can speak for compilers for real CPUs, I'm not sure about JVM compiler and I don't think that at compile level code is optimized as much as you think (the Java platform simply don't care too much about memory foorprint as you can imagine). 我可以代表真正的CPU编译器,我不确定JVM编译器,我不认为在编译级别代码的优化程度与你想象的一样(Java平台根本不关心内存foorprint如何你可以想象)。
For real compilers these scenarios are actually optimized very often. 对于真正的编译器,这些场景实际上经常被优化。 This is done not at high level language level but at a lower intermediate level like at RTL level.
这不是在高级语言级别,而是在较低的中级水平,如RTL级别。 Everything is made with the purpose of register allocation or stack allocation and works by computing living sets for variables inside functions.
一切都是为了寄存器分配或堆栈分配的目的,并通过计算函数内部变量的生存集来工作。
This means that when the code is compiled everything is translated to RTL by assuming an arbitrary number of temporary registers and then for each temporary, its live state is calculated through the so-called live variable analysis . 这意味着当编译代码时,通过假定任意数量的临时寄存器将所有内容转换为RTL,然后对于每个临时寄存器,通过所谓的实时变量分析来计算其实时状态。 This is just one of the ways to optimize such things.
这只是优化此类事物的方法之一。
Eg 例如
This is done after having splitted the code into blocks which does not contain jumps or labels so that you are sure about the flow inside any specified block. 这是在将代码拆分为不包含跳转或标签的块之后完成的,这样您就可以确定任何指定块内的流。
After this computation you can easily see which variables are needed for most time, which become useless and can free their reserved space and so on. 在这个计算之后,您可以很容易地看到大多数时间需要哪些变量,这些变量变得无用并且可以释放它们的预留空间等等。 This is done so that you are able to fit as much variables as possible into registers and optimize the assembled code a lot.
这样做是为了使您能够将尽可能多的变量放入寄存器并大量优化汇编代码。
Personally I don't think the javac does any of this (even because the JVM is stack based so this would just break memory allocation on objects without any need nowadays), but my is just speculation. 我个人认为javac没有做到这一点(即使因为JVM是基于堆栈的,所以这只会破坏对象上的内存分配而现在没有任何需要),但我只是猜测。
Yes. 是。 The stack slot can be reused after the nested }, and I have seen javac do so.
堆栈插槽可以在嵌套}之后重用,我看到javac这样做了。
Yes. 是。 Cases 1 and 2 are equivalent.
案例1和案例2相同。 The second nested {} changes nothing, unless something follows it.
第二个嵌套{}没有任何改变,除非它跟随它。
The Java compiler won't optimize this, although in theory given all the right conditions it conceivably could. Java编译器不会对此进行优化,尽管在理论上给出了它可以想到的所有正确条件。 If the variables are final it is possible not to assign a slot for them at all.
如果变量是最终的,则可能根本不为它们分配槽。
Another thing you should note is that there is no byte code instruction corresponding to the nested }, so the JVM and therefore HotSpot has no basis for knowing where a nested scope ends and therefore where a stack slot changes usage. 您应该注意的另一件事是没有与嵌套}相对应的字节代码指令,因此JVM和HotSpot没有基础知道嵌套作用域的结束位置,因此堆栈插槽更改使用的位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.