今天偶然与建议不要用for,可读性太差性能又低,可我个人认为要根据具体情况而定,毕竟for在大部分语言的关键字,可读性不可能因为一个关键字的替代而变好,多数取决于设计和编码习惯。
至于性能,打算写段代码对它们分别测试一下。
- var arr = Enumerable.Range(0, 100000000).ToList();var sw = Stopwatch.StartNew();for(var i = 0;i
先看生成的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.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.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 ...登录后复制
首先可以看到很多方法调用,并且在循环体内部每次都要调用方法MoveNext。最后可以看到,有end finally,意味着这个循环外部包了一层try-finally。从IL来看,foreach要比for慢的多了。
现在来看StopWatch的执行结果。
for loop takes : 764538for loop takes : 1311252登录后复制
for几乎快了一倍。
结论:编程语言提供的关键字是为了解决某种问题而存在,需要对具体的业务场景进行判断再决定,有关性能方面,一定要拿出数据说话。
以上就是c#, for vs foreach的内容,更多相关内容请关注PHP中文网(www.php.cn)!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。