На самом деле, foreach над int [] компилируется в оператор 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)));
}
}