Легкий тест для полуутверждения. Я сделал небольшой тест, просто чтобы увидеть. Вот код:
static void Main(string[] args)
{
List<int> intList = new List<int>();
for (int i = 0; i < 10000000; i++)
{
intList.Add(i);
}
DateTime timeStarted = DateTime.Now;
for (int i = 0; i < intList.Count; i++)
{
int foo = intList[i] * 2;
if (foo % 2 == 0)
{
}
}
TimeSpan finished = DateTime.Now - timeStarted;
Console.WriteLine(finished.TotalMilliseconds.ToString());
Console.Read();
}
А вот секция foreach:
foreach (int i in intList)
{
int foo = i * 2;
if (foo % 2 == 0)
{
}
}
Когда я заменил на с Еогеаспом - в цикле , была 20 миллисекунд быстрее - последовательно . Значение for было 135–139 мс, а значение foreach - 113–119 мс. Я несколько раз менял местами, чтобы убедиться, что это не какой-то процесс, который просто запустился.
Однако, когда я удалил операторы foo и if, for было быстрее на 30 мс (foreach было 88 мсек, а for было 59 мсек). Оба были пустыми снарядами. Я предполагаю, что foreach действительно передал переменную, в то время как for просто увеличивал переменную. Если бы я добавил
int foo = intList[i];
Затем for становится медленным примерно на 30 мс. Я предполагаю, что это было связано с созданием foo, захватом переменной в массиве и присвоением ее foo. Если вы просто обращаетесь к intList [i], вы не получаете этого штрафа.
Честно говоря .. Я ожидал, что foreach будет немного медленнее при любых обстоятельствах, но этого недостаточно, чтобы иметь значение для большинства приложений.
edit: вот новый код с использованием предложений Джонса (134217728 - это самый большой int, который вы можете иметь до того, как будет выбрано исключение System.OutOfMemory):
static void Main(string[] args)
{
List<int> intList = new List<int>();
Console.WriteLine("Generating data.");
for (int i = 0; i < 134217728 ; i++)
{
intList.Add(i);
}
Console.Write("Calculating for loop:\t\t");
Stopwatch time = new Stopwatch();
time.Start();
for (int i = 0; i < intList.Count; i++)
{
int foo = intList[i] * 2;
if (foo % 2 == 0)
{
}
}
time.Stop();
Console.WriteLine(time.ElapsedMilliseconds.ToString() + "ms");
Console.Write("Calculating foreach loop:\t");
time.Reset();
time.Start();
foreach (int i in intList)
{
int foo = i * 2;
if (foo % 2 == 0)
{
}
}
time.Stop();
Console.WriteLine(time.ElapsedMilliseconds.ToString() + "ms");
Console.Read();
}
И вот результаты:
Создание данных. Расчет для цикла: 2458 мс Расчет для каждого цикла: 2005 мс
Их перестановка местами, чтобы увидеть, имеет ли он дело с порядком вещей, дает те же результаты (почти).