[英]What is the difference between “for(int i=0,length=list.size;i<length;i++) ” and “for(int i=0;i<list.size;i++) ”?
I saw two ways of writing for loops. 我看到了两种编写循环的方法。
for( int i = 0, length = list.size(); i < length; i++ )
and 和
for( int i = 0; i < list.size(); i++ )
Is their performance the same? 他们的表现是一样的吗? Will the jvm optimize the difference? jvm是否会优化差异?
These two for loops are not equivalent when the size changes while in the loop block. 当在循环块中更改大小时,这两个for循环并不等效。 The first one may fail with an index out of range or may miss added elements. 第一个可能因索引超出范围而失败,或者可能错过添加的元素。
Performance: Compilers optimize the most common cases. 性能:编译器优化最常见的情况。 So I wouldn't do anything special to try to optimize something as common as looping a collection. 因此,我不会做任何特别的尝试来尝试优化像循环集合一样常见的操作。
The key difference is that the first way only calls list.size()
once instead of on each iteration. 关键区别在于,第一种方法只调用一次list.size()
,而不是每次迭代都调用一次。 It's unlikely to be useful with a simple list, but it can be helpful when it's expensive to compute length
; 用一个简单的列表不太可能有用,但是当计算length
很昂贵时它可能会有用。 for example, when iterating over a NodeList
例如,当遍历NodeList
Please try to make code easier to read to help answer your questions. 请尝试使代码更易于阅读,以帮助回答您的问题。
The following tests are based on javase 8: 以下测试基于Javase 8:
i will list the java byte codes for the two different codes: 我将列出两种不同代码的Java字节代码:
public void gg1(List<String> list){
for(int i = 0, length = list.size(); i < length; i++){
}
}
the byte code is: 字节码为:
public gg1(Ljava/util/List;)V
L0
LINENUMBER 10 L0
ICONST_0
ISTORE 2
L1
ALOAD 1
INVOKEINTERFACE java/util/List.size ()I
ISTORE 3
L2
GOTO L3
L4
FRAME APPEND [I I]
IINC 2 1
L3
FRAME SAME
ILOAD 2
ILOAD 3
IF_ICMPLT L4
L5
LINENUMBER 13 L5
RETURN
L6
LOCALVARIABLE this Lcom/trans/test/Test14; L0 L6 0
LOCALVARIABLE list Ljava/util/List; L0 L6 1
// signature Ljava/util/List<Ljava/lang/String;>;
// declaration: java.util.List<java.lang.String>
LOCALVARIABLE i I L1 L5 2
LOCALVARIABLE length I L2 L5 3
MAXSTACK = 2
MAXLOCALS = 4
Now in the other code: 现在在其他代码中:
public void gg2(List<String> list){
for(int i = 0; i < list.size(); i++){
}
}
the byte code is: 字节码为:
public gg2(Ljava/util/List;)V
L0
LINENUMBER 16 L0
ICONST_0
ISTORE 2
L1
GOTO L2
L3
FRAME APPEND [I]
IINC 2 1
L2
FRAME SAME
ILOAD 2
ALOAD 1
INVOKEINTERFACE java/util/List.size ()I
IF_ICMPLT L3
L4
LINENUMBER 19 L4
RETURN
L5
LOCALVARIABLE this Lcom/trans/test/Test14; L0 L5 0
LOCALVARIABLE list Ljava/util/List; L0 L5 1
// signature Ljava/util/List<Ljava/lang/String;>;
// declaration: java.util.List<java.lang.String>
LOCALVARIABLE i I L1 L4 2
MAXSTACK = 2
MAXLOCALS = 3
It can be seen that the list.size() method will be invoked in every iteration of gg2, and invoked once in the method gg1. 可以看出,list.size()方法将在gg2的每次迭代中被调用,并在方法gg1中被调用一次。 Therefore, gg1 is more efficient! 因此,gg1更有效!
I hope this helps answer your question! 希望这有助于回答您的问题!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.