我看到了两种写循环方式。
for( int i = 0, length = list.size(); i < length; i++ )
和
for( int i = 0; i < list.size(); i++ )
他们的表现是否相同? jvm会优化差异吗?
答案 0 :(得分:1)
当在循环块中更改大小时,这两个for循环不相等。第一个可能会因索引超出范围而失败,或者可能会错过添加的元素。
性能:编译器优化最常见的情况。因此,我不会做任何特别的尝试来优化像循环集合那样常见的东西。
答案 1 :(得分:1)
关键区别在于第一种方式只调用length
一次而不是每次迭代。对于简单的列表,它不太可能有用,但如果计算Exception in thread "main" org.apache.spark.sql.AnalysisException: cannot resolve '`queryResults`.`searchResponse`.`response`.`docs`.`transactions`['code']' due to data type mismatch: argument 2 requires integral type, however, ''code'' is of string type.;;
的代价很高,则会很有用;例如,当iterating over a NodeList
答案 2 :(得分:0)
请尝试使代码更易于阅读以帮助回答您的问题。
以下测试基于javase 8:
我将列出两个不同代码的java字节代码:
public void gg1(List<String> list){
for(int i = 0, length = list.size(); i < length; i++){
}
}
字节代码是:
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
现在在其他代码中:
public void gg2(List<String> list){
for(int i = 0; i < list.size(); i++){
}
}
字节代码是:
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
可以看出list.size()方法将在gg2的每次迭代中调用,并在方法gg1中调用一次。因此,gg1更有效率!
我希望这有助于回答你的问题!