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