简体   繁体   中英

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?

These two for loops are not equivalent when the size changes while in the loop block. 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. It's unlikely to be useful with a simple list, but it can be helpful when it's expensive to compute length ; for example, when iterating over a NodeList

Please try to make code easier to read to help answer your questions.

The following tests are based on javase 8:

i will list the java byte codes for the two different codes:

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. Therefore, gg1 is more efficient!

I hope this helps answer your question!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM