今天我们在工作中进行了讨论,这两个函数的性能更高,内存消耗更少,并且不会对gc造成压力。
public class Main {
public void do1() {
int result = 0;
int val;
do {
val = calc(result);
result = val * 2;
} while (result < 1000);
}
public void do2() {
int result = 0;
do {
final int val = calc(result);
result = val * 2;
} while (result < 1000);
}
private int calc(final int i) {
return i + 2;
}
}
在我看来两者都是等价的,如果在循环内部或外部定义 val 并不重要。我脑海中唯一想到的是变量范围应尽可能缩小。但是,我们讨论gc如何处理这些情况并且我们没有找到解决方案。
我们查看了字节码并没有区别
Compiled from "Main.java"
public class Main {
public Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void do1();
Code:
0: iconst_0
1: istore_1
2: aload_0
3: iload_1
4: invokespecial #2 // Method calc:(I)I
7: istore_2
8: iload_2
9: iconst_2
10: imul
11: istore_1
12: iload_1
13: sipush 1000
16: if_icmplt 2
19: return
public void do2();
Code:
0: iconst_0
1: istore_1
2: aload_0
3: iload_1
4: invokespecial #2 // Method calc:(I)I
7: istore_2
8: iload_2
9: iconst_2
10: imul
11: istore_1
12: iload_1
13: sipush 1000
16: if_icmplt 2
19: return
}
有人知道这里是否真的没有区别或能否解决讨论?
答案 0 :(得分:2)
正如您在检查字节码时看到的那样,Java没有区别。您可能会在其他语言中看到一些差异,例如,如果在C中编写相同的代码。
所以在你的情况下,论证是关于化妆品和可维护性。
我认为使用最具体的范围界定 - 如do2
- 更好,因为:
不同点,但在您的示例中,我甚至认为您可以在下一个表达式中内联val
变量。不这样做只会增加噪音。但我认为这样做是为了示例或打印出值。
答案 1 :(得分:-1)
没有区别。由于没有分配new
个对象,因此这些都没有与垃圾收集器进行任何交互。 int
变量在堆栈上分配。
这反映在每个相同的字节码中。