实际上,一个 int[] 上的 foreach 被编译成一个 for 语句。如果我们将它转换为可枚举,你是对的,它使用枚举器。 然而,奇怪的是,它更快,因为没有增加 temp int。 为了证明这一点,我们使用基准测试和反编译器来增加理解......
所以我认为通过问这个问题,你真的自己回答了。
如果此基准与您的不同,请告诉我如何。我用对象数组、空值等进行了尝试……
代码:
static void Main(string[] args)
{
int[] ints = Enumerable.Repeat(1, 50000000).ToArray();
while (true)
{
DateTime now = DateTime.Now;
for (int i = 0; i < ints.Length; i++)
{
//nothing really
}
Console.WriteLine("for loop: " + (DateTime.Now - now));
now = DateTime.Now;
for (int i = 0; i < ints.Length; i++)
{
int nothing = ints[i];
}
Console.WriteLine("for loop with assignment: " + (DateTime.Now - now));
now = DateTime.Now;
foreach (int i in ints)
{
//nothing really
}
Console.WriteLine("foreach: " + (DateTime.Now - now));
now = DateTime.Now;
foreach (int i in (IEnumerable<int>)ints)
{
//nothing really
}
Console.WriteLine("foreach casted to IEnumerable<int>: " + (DateTime.Now - now));
}
}
结果:
for loop: 00:00:00.0273438
for loop with assignment: 00:00:00.0712890
foreach: 00:00:00.0693359
foreach casted to IEnumerable<int>: 00:00:00.6103516
for loop: 00:00:00.0273437
for loop with assignment: 00:00:00.0683594
foreach: 00:00:00.0703125
foreach casted to IEnumerable<int>: 00:00:00.6250000
for loop: 00:00:00.0273437
for loop with assignment: 00:00:00.0683594
foreach: 00:00:00.0683593
foreach casted to IEnumerable<int>: 00:00:00.6035157
for loop: 00:00:00.0283203
for loop with assignment: 00:00:00.0771484
foreach: 00:00:00.0771484
foreach casted to IEnumerable<int>: 00:00:00.6005859
for loop: 00:00:00.0273438
for loop with assignment: 00:00:00.0722656
foreach: 00:00:00.0712891
foreach casted to IEnumerable<int>: 00:00:00.6210938
反编译(请注意,空的 foreach 必须添加一个变量赋值......我们的空 for 循环没有但显然需要):
private static void Main(string[] args)
{
int[] ints = Enumerable.Repeat<int>(1, 0x2faf080).ToArray<int>();
while (true)
{
DateTime now = DateTime.Now;
for (int i = 0; i < ints.Length; i++)
{
}
Console.WriteLine("for loop: " + ((TimeSpan) (DateTime.Now - now)));
now = DateTime.Now;
for (int i = 0; i < ints.Length; i++)
{
int num1 = ints[i];
}
Console.WriteLine("for loop with assignment: " + ((TimeSpan) (DateTime.Now - now)));
now = DateTime.Now;
int[] CS$6$0000 = ints;
for (int CS$7$0001 = 0; CS$7$0001 < CS$6$0000.Length; CS$7$0001++)
{
int num2 = CS$6$0000[CS$7$0001];
}
Console.WriteLine("foreach: " + ((TimeSpan) (DateTime.Now - now)));
now = DateTime.Now;
using (IEnumerator<int> CS$5$0002 = ((IEnumerable<int>) ints).GetEnumerator())
{
while (CS$5$0002.MoveNext())
{
int current = CS$5$0002.Current;
}
}
Console.WriteLine("foreach casted to IEnumerable<int>: " + ((TimeSpan) (DateTime.Now - now)));
}
}