Una prueba fácil de semi-validar. Hice una pequeña prueba, solo para ver. Aquí está el código:
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();
}
Y aquí está la sección de foreach:
foreach (int i in intList)
{
int foo = i * 2;
if (foo % 2 == 0)
{
}
}
Cuando reemplacé el for con un foreach, el foreach fue 20 milisegundos más rápido, consistentemente . El for fue de 135-139ms mientras que el foreach fue de 113-119ms. Cambié de un lado a otro varias veces, asegurándome de que no fuera un proceso que simplemente se inició.
Sin embargo, cuando eliminé el foo y la instrucción if, el for fue más rápido en 30 ms (foreach fue de 88 ms y for fue de 59 ms). Ambos eran cascos vacíos. Supongo que el foreach realmente pasó una variable donde el for solo estaba incrementando una variable. Si agregué
int foo = intList[i];
Luego, el for se vuelve lento en unos 30 ms. Supongo que esto tuvo que ver con la creación de foo y tomando la variable en la matriz y asignándola a foo. Si solo accede a intList [i], entonces no tiene esa penalización.
Honestamente ... esperaba que foreach fuera un poco más lento en todas las circunstancias, pero no lo suficiente como para importar en la mayoría de las aplicaciones.
editar: aquí está el nuevo código usando las sugerencias de Jons (134217728 es el mayor int que puede tener antes de que se lance la excepción 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();
}
Y aquí están los resultados:
Generando datos. Cálculo de bucle for: 2458ms Cálculo de bucle foreach: 2005ms
Al intercambiarlos para ver si se trata del orden de las cosas, se obtienen los mismos resultados (casi).