For vs foreach in c #
Today, we occasionally recommend that you do not use for. The readability is too poor and the performance is low, but I personally think it depends on the specific situation. After all, for keywords in most languages, readability cannot be improved due to the substitution of a keyword, most of which depends on the design and coding habits.
As for the performance, I plan to write some code to test them separately.
var arr = Enumerable.Range(0, 100000000).ToList();var sw = Stopwatch.StartNew();for(var i = 0;i < arr.Count; i++){}sw.Stop();Console.WriteLine("for loop takes : " + sw.ElapsedTicks);sw = Stopwatch.StartNew();foreach(var x in arr){}sw.Stop();Console.WriteLine("for loop takes : " + sw.ElapsedTicks);
First look at the generated IL
For Loop:
...IL_0018: ldc.i4.0 IL_0019: stloc.2 // iIL_001A: br.s IL_0022IL_001C: nop IL_001D: nop IL_001E: ldloc.2 // iIL_001F: ldc.i4.1 IL_0020: add IL_0021: stloc.2 // iIL_0022: ldloc.2 // iIL_0023: ldloc.0 // arrIL_0024: callvirt System.Collections.Generic.List
.get_CountIL_0029: clt IL_002B: stloc.s 04 // CS$4$0000IL_002D: ldloc.s 04 // CS$4$0000IL_002F: brtrue.s IL_001C...
Except that callvirt in IL_0024 triggers the method virtual Table query, there are almost no high-consumption commands. Let's take a look at the foreach IL section:
...IL_005A: ldloc.0 // arrIL_005B: callvirt System.Collections.Generic.List
.GetEnumeratorIL_0060: stloc.s 05 // CS$5$0001IL_0062: br.s IL_006EIL_0064: ldloca.s 05 // CS$5$0001IL_0066: call System.Collections.Generic.List
+Enumerator.get_CurrentIL_006B: stloc.3 // xIL_006C: nop IL_006D: nop IL_006E: ldloca.s 05 // CS$5$0001IL_0070: call System.Collections.Generic.List
+Enumerator.MoveNextIL_0075: stloc.s 04 // CS$4$0000IL_0077: ldloc.s 04 // CS$4$0000IL_0079: brtrue.s IL_0064IL_007B: leave.s IL_008CIL_007D: ldloca.s 05 // CS$5$0001IL_007F: constrained. System.Collections.Generic.List<>.EnumeratorIL_0085: callvirt System.IDisposable.DisposeIL_008A: nop IL_008B: endfinally IL_008C: nop ...
First, we can see a lot of method calls and call the MoveNext method every time within the loop body. Finally, we can see that there is end finally, which means that this loop contains a layer of try-finally. From the perspective of IL, foreach is much slower than.
Now let's look at the execution result of StopWatch.
for loop takes : 764538for loop takes : 1311252
For is almost doubled.
Conclusion: The keywords provided by the programming language exist to solve a certain problem. It is necessary to judge the specific business scenario before deciding. In terms of performance, we must speak out the data.