首先,我请那些有“过早优化”恐惧症的人放过我:我不想优化任何东西,我只是好奇。
我阅读/观察了两件事,包括在 stackoverflow 上(现在找不到链接):
- 对于方法调用,所有局部变量的内存都保留在方法的“开头”,即即使是在较低级别范围内声明的变量(我知道这在科学上是糟糕的措辞,例如忽略调用机制的工作原理等。 ,但我希望这一点很清楚)。显然,运行程序不存在作用域,它们只是在源代码级别上,以提高可读性、可维护性、代码结构、告诉编译器我们的意图(例如给出优化提示,见下文)。
- 在尽可能小的范围内(即仍然需要它们的最高级别)声明变量的优点之一是“编译器可以将内存重用于其他临时变量(在其他块中)”。这对我来说听起来既清晰又合乎逻辑。
我想知道编译器/JIT/什么可以实际优化,什么不能。
这是以下方法(假设实际使用了变量,因此无法优化它们):
// 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.) 编译器是否能够检测到 and 的空间var2
可以var3
用于var4
and var5
?我不记得在反汇编的字节码中看到过这样的事情。
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
}
}
最后,让我们看一个更简单的案例:
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.)在这种情况下,var1
内存可以重用var4
(或var5
)吗?即在这种情况下,该方法有两个局部int
变量的内存就足够了,而不是三个。
(我知道理论上,这些对于编译器来说是显而易见的情况,但有时我会忽略一些事情,例如为什么编译器不能做或假设任何事情。)