哪个代码段可以提供更好的性能?以下代码段是用C#编写的。
1。
for(int counter=0; counter<list.Count; counter++) { list[counter].DoSomething(); }
2。
foreach(MyType current in list) { current.DoSomething(); }
好吧,部分取决于的确切类型list。它还取决于您使用的确切CLR。
list
它是否 有意义 ,将取决于您是否在循环中进行任何实际工作。在几乎 所有 情况下,对性能的影响都不是很大,但对可读性的影响则有利于foreach循环。
foreach
我个人也会使用LINQ来避免出现“ if”:
foreach (var item in list.Where(condition)) { }
编辑:对于那些声称对List<T>with进行迭代foreach产生与for循环相同代码的人来说,以下证据表明它不会:
List<T>
for
static void IterateOverList(List<object> list) { foreach (object o in list) { Console.WriteLine(o); } }
产生IL:
.method private hidebysig static void IterateOverList(class [mscorlib]System.Collections.Generic.List`1<object> list) cil managed { // Code size 49 (0x31) .maxstack 1 .locals init (object V_0, valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object> V_1) IL_0000: ldarg.0 IL_0001: callvirt instance valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<!0> class [mscorlib]System.Collections.Generic.List`1<object>::GetEnumerator() IL_0006: stloc.1 .try { IL_0007: br.s IL_0017 IL_0009: ldloca.s V_1 IL_000b: call instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object>::get_Current() IL_0010: stloc.0 IL_0011: ldloc.0 IL_0012: call void [mscorlib]System.Console::WriteLine(object) IL_0017: ldloca.s V_1 IL_0019: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object>::MoveNext() IL_001e: brtrue.s IL_0009 IL_0020: leave.s IL_0030 } // end .try finally { IL_0022: ldloca.s V_1 IL_0024: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object> IL_002a: callvirt instance void [mscorlib]System.IDisposable::Dispose() IL_002f: endfinally } // end handler IL_0030: ret } // end of method Test::IterateOverList
编译器对 数组的 处理方式不同,foreach基本上将for循环转换为循环,但不转换为List<T>。这是数组的等效代码:
static void IterateOverArray(object[] array) { foreach (object o in array) { Console.WriteLine(o); } } // Compiles into... .method private hidebysig static void IterateOverArray(object[] 'array') cil managed { // Code size 27 (0x1b) .maxstack 2 .locals init (object V_0, object[] V_1, int32 V_2) IL_0000: ldarg.0 IL_0001: stloc.1 IL_0002: ldc.i4.0 IL_0003: stloc.2 IL_0004: br.s IL_0014 IL_0006: ldloc.1 IL_0007: ldloc.2 IL_0008: ldelem.ref IL_0009: stloc.0 IL_000a: ldloc.0 IL_000b: call void [mscorlib]System.Console::WriteLine(object) IL_0010: ldloc.2 IL_0011: ldc.i4.1 IL_0012: add IL_0013: stloc.2 IL_0014: ldloc.2 IL_0015: ldloc.1 IL_0016: ldlen IL_0017: conv.i4 IL_0018: blt.s IL_0006 IL_001a: ret } // end of method Test::IterateOverArray
有趣的是,我在任何地方都找不到C#3规范中记录的内容…