List Benchmark: Size=1000, Runs=50000, Total Time = 19.5 sec
var list = new List<string>(Size); for (int i = 0; i < Size; i++) list.Add(i.ToString()); var b = new Benchmark(); b.Test("TestListIteration", () => { c = 0; for (int i = 0; i < Runs; i++) { for (int j = 0; j < Size; j++) { c += list[j].Length; } } }); List To Array Benchmark: Size=1000, Runs=50000, Total Time=15.449
var list = new List<string>(Size); for (int i = 0; i < Size; i++) list.Add(i.ToString()); var b = new Benchmark(); b.Test("TestListIteration", () => { c = 0; for (int i = 0; i < Runs; i++) { var array = list.ToArray(); //Changed line here !!! for (int j = 0; j < Size; j++) { c += array[j].Length; } } }); Isn't this a paradox ?
How can performing two actions
a) converting entire list to array and
b) iterating entire array.
Be faster than doing b alone (iterating list).
If this is the case, then it means than all code written in the world is wrong. We should have predicted for this case. And each "For" loop on a list should automatically call .ToArray before it starts. Even if the array is discarded later.
Edit: Here are the Results depending on the "Size".
Size=10, Runs=5000000: List Wins List : 20.362, ListToArray: 37.36
Size=100, Runs=500000: List Wins List : 19.64, ListToArray: 23.162
Size=1000, Runs=50000: ListToArray Wins List : 19.5, ListToArray: 15.449
Size=10000, Runs=5000: ListToArray Wins List : 20.094, ListToArray: 14.453
Size=10000000, Runs=5: Computer died
list[j]presumably implicitly casts the list to an array, as index-based retrieval has been the way to interact with arrays, not lists. This means that you are implicitly casting the list to an array for every iteration, as opposed to doing it once and then using the array without a need to still cast it.Listis an array. So doinglist[i]is making at least two function calls (the [] of thelist[i]is a function call, then another function call internally to get the underlying array) and then array subscripting wherearray[i]is doing just array subscripting.