今天偶然與建議不要用for,可讀性太差效能又低,可我個人認為要根據具體情況而定,畢竟for在大部分語言的關鍵字,可讀性不可能因為一個關鍵字的替代而變好,多數取決於設計和編碼習慣。
至於效能,打算寫段代碼對它們分別測試一下。
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);
先看產生的IL
for迴圈的部分:
...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<System.Int32>.get_CountIL_0029: clt IL_002B: stloc.s 04 // CS$4$0000IL_002D: ldloc.s 04 // CS$4$0000IL_002F: brtrue.s IL_001C...
除了IL_0024中的callvirt會觸發方法虛表查詢外,幾乎不存在任何高消耗的指令。再來看foreach的IL部分:
...IL_005A: ldloc.0 // arrIL_005B: callvirt System.Collections.Generic.List<System.Int32>.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<System.Int32>+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<System.Int32>+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 ...
首先可以看到很多方法調用,並且在迴圈體內部每次都要調用方法MoveNext。最後可以看到,有end finally,意味著這個迴圈外部包了一層try-finally。從IL來看,foreach要比for慢的多了。
現在來看StopWatch的執行結果。
for loop takes : 764538for loop takes : 1311252
for幾乎快了一倍。
結論:程式設計語言提供的關鍵字是為瞭解決某種問題而存在,需要對具體的業務情境進行判斷再決定,有關效能方面,一定要拿出資料說話。
以上就是c#, for vs foreach的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!