Object[] objs = new Object[5];
for (int i = 0; i < 5; ++i) {
int j = i + 1;
Object obj = objs[i];
}
我对上述循环有两个问题:
j
变量和obj
引用,还是只创建了一次,然后才重新分配值?++i
而不是i++
作为增加值的单个指令,是否有任何性能优势?答案 0 :(得分:7)
是为每个循环迭代创建了j变量和obj引用,还是只创建了一次,然后只重新赋值?
每次声明和创建
将++ i而不是i ++作为单个指令来增加值是否有任何性能优势?
不是。
答案 1 :(得分:6)
是为每次循环迭代创建了j变量和obj引用,还是只创建了一次,然后只重新赋值?
每次循环时,都会创建一个新的int,但obj只是对现有对象的引用,因此不会触发对象创建。无论如何,JVM很可能会为您优化它。
将++ i而不是i ++作为单个指令来增加值是否有任何性能优势?
很可能没什么特别的,再一次,JVM可能会改变你的代码。
底线:使用更具可读性的内容,并将变量的范围限制在使用它们的位置。
实际上,JVM可能会将您的代码更改为此,因为您不在循环中使用局部变量:
Object[] objs = new Object[5];
//for (int i = 0; i < 5; ++i) {
// int j = i + 1;
// Object obj = objs[i];
//}
答案 2 :(得分:3)
我比较了代码部分的两个字节码。我没有发现什么特别的。唯一的区别是,在第一个样本代码部分中定义了4个局部变量,但在第二个样本代码部分中定义了5个局部变量。但是执行类似的操作码。由于局部变量名称不同,因此执行差异操作码。我的意思是在第一个例子中'我被定义为局部变量-2',在第二个例子中'我被定义为局部变量-4'。
但是通过JVM工具监视代码执行可以提供额外的信息。由于Java是一个平台而JVM可能会优化代码执行,因此我们可能无法通过查看java源代码或java字节码来确定它。
Object[] objs = new Object[5];
for (int i = 0; i < 5; ++i) {
int j = i + 1;
Object obj = objs[i];
}
local-variable-0=this
local-variable-1=objs
local-variable-2=i
local-variable-3=j
stack=2, locals=5, args_size=1
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: iconst_5
5: anewarray #3 // class java/lang/Object
8: astore_1 #store created object referance to local value-1 (objs)
9: iconst_0 #push 0 on stack
10: istore_2 # local-value-2(i) assigned 0
11: goto 26
14: iload_2 #load localvalue 2(i)
15: iconst_1 # ++i operation
16: iadd #i+1
17: istore_3 #assign i+1 into local-variable-3(j)
18: aload_1 # push object in local varable 1 (objs) onto the stack
19: iload_2 # push integer in local variable 2 (i) onto the stack
20: aaload # retrieve entry
21: astore 4 # push value on stack into local-variable-4 (obj)
23: iinc 2, 1 # local-variable-2(i)++
26: iload_2
27: iconst_5
28: if_icmplt 14 for(if i==5)
31: return
**************************************************************************
Object[] objs = new Object[5];
int j;
Object obj;
for (int i = 0; i < 5; ++i) {
j = i + 1;
obj = objs[i];
}
local-variable-0=this
local-variable-1=objs
local-variable-2=j
local-variable-3=obj
local-variable-4=i
stack=2, locals=5, args_size=1
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: iconst_5
5: anewarray #3 // class java/lang/Object
8: astore_1 #store created object referance to local value-1 (objs)
9: iconst_0 #push zero on to the stack
10: istore 4 # local variable-4(i) is assigned zero
12: goto 28
15: iload 4
17: iconst_1
18: iadd #i+1
19: istore_2 #j is set
20: aload_1 #load objs
21: iload 4 #load i
23: aaload
24: astore_3 #obj=objs[i]
25: iinc 4, 1 # i++
28: iload 4
30: iconst_5
31: if_icmplt 15 # if i==5
34: return
答案 3 :(得分:1)
是的,他们是!
这样做:
Object[] objs = new Object[5];
int j = 0;
Object obj = new Object();
for (int i = 0; i < 5; ++i) {
j = i + 1;
obj = objs[i];
}
答案 4 :(得分:1)
是的,他们每次创建,前缀或后缀++无关紧要。
答案 5 :(得分:1)
是为每次循环迭代创建了j变量和obj引用,还是只创建了一次,然后只重新赋值?
理论上是的。在实践中,优化代码不会发生。但是,在您的情况下,可能不会优化5(或小于10,000)的循环,因为性能不太重要。
将++ i而不是i ++作为单个指令来增加值是否有任何性能优势?
对于优化代码,它们在这里是相同的。对于未经优化的代码,差异不太重要。
答案 6 :(得分:1)
我会尽力回答你的问题......
Are the j variable and obj reference created for every loop iteration or they are created
once and then only reassigned the values?
int j
每次都创建,Object Reference Variable obj
每次在循环中也创建,但是 NOT THE OBJECT
。
Is there any perfomance benefit of putting ++i instead of i++ as a single instruction to
increment the value?
如果未分配 j's value
,则无关紧要。