Comparison of traversal performance between ArrayList and LinkedList

Keywords: Android Java C

An example is used to test the traversal performance of ArrayList and LinkedList.

Structural differences:

There are two kinds of lists commonly used by us, ArrayList and LinkedList. Although both are list, the performance of different traversal methods varies greatly due to different internal storage structures.

Characteristics of Lis t storage structure

The ArrayList array structure can be directly valued according to the subscript.

If the LinkedList structure needs to find a subscript value, it must be traversed from the beginning.

Common practice:

We may do this when traversing the List (habits brought by C language):

  public void loopList(List<Integer> lists) {
    for (int i=0; i< lists.size(); i++) {
      Integer integer = lists.get(i);
      // TODO processing data
   }
}
//Copy code

This approach is very intuitive. At first glance, it doesn't seem to be a problem, but after careful analysis, we can see that the performance of using ArrayList and LinkedList in this case is totally different.

List cycle time complexity get(i) time complexity total time complexity

ArrayList O(n) O(1) O(n)

LinkedList O(n) O(n) O(n2)

In terms of time complexity, the two are directly one order of magnitude different, which may not be obvious. In order to express intuitively, code test is used to process 10000 pieces of data efficiency: performance test:

Create data:

ArrayList<Integer> arrayList = new ArrayList<>();
LinkedList<Integer> linkedList = new LinkedList<>();
for (int i=0; i<10000; i++){
   arrayList.add(i);
   linkedList.add(i);
//Copy code

}Test For recycle:

 long startTime1=System.currentTimeMillis();   //Get start time
  loopList(arrayList);
 iteratorList(arrayList);
    long endTime1=System.currentTimeMillis(); //Get end time
  Log.i("Time", "For-ArrayList:  "+(endTime1-startTime1)+"ms");
  
  long startTime2=System.currentTimeMillis();   //Get start time
   loopList(linkedList);
   long endTime2=System.currentTimeMillis(); //Get end time
    Log.i("Time", "For-LinkedList: "+(endTime2-startTime2)+"ms");
//Copy code

Result:

  com.gcssloop.alltest I/Time: For-ArrayList:  20ms

  com.gcssloop.alltest I/Time: For-LinkedList: 648ms
//Copy code

It can be seen that the time required to process only 10000 pieces of data can hardly be compared. When the amount of data becomes larger and larger, LinkedList will inevitably consume more time. Treatment method:

We have iterators and ForEach loops in Java, which can be used to replace the original for loop.

Iterator:

   public void iteratorList(List<Integer> lists){
      Iterator<Integer> it = lists.iterator();
      while (it.hasNext()){
        Integer integer = it.next();
        // TODO processing data
}
//Copy code

}The test code is similar to the above, so it is omitted.

Result:

 com.gcssloop.alltest I/Time: Iterator-ArrayList:  4ms

  com.gcssloop.alltest I/Time: Iterator-LinkedList: 6ms
//Copy code

It can be seen that the final cost of time is almost the same and both of them are greatly improved.

ForEach loop:

  public void foreachList(List<Integer> lists){
     for (Integer i : lists) {
       // TODO processing data
 }
}
//Copy code

Performance:

 com.gcssloop.alltest I/Time: ForEach-ArrayList:  5ms

   com.gcssloop.alltest I/Time: ForEach-LinkedList: 5ms
//Copy code

Because the lower layer of ForEach loop also uses iterators, it has similar performance to iterators.

Conclusion:

It is recommended to use iterator and ForEach to traverse List instead of traditional For loop.

The following is the test processing 10000 data performance:

The values are for reference only, and are related to the operating environment. Each test result may be slightly different.

Iteration method ArrayList LinkedListFor

Cycle 20ms6 48ms

Iterator 4ms 6ms

For each cycle 5ms 5ms

Posted by tress on Thu, 17 Oct 2019 07:12:41 -0700