Um teste fácil de semivalidar. Fiz um pequeno teste, só para ver. Aqui está o 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();
}
E aqui está a seção foreach:
foreach (int i in intList)
{
int foo = i * 2;
if (foo % 2 == 0)
{
}
}
Quando substituí o for por um foreach - o foreach foi 20 milissegundos mais rápido - de forma consistente . O for foi de 135-139ms, enquanto o foreach foi de 113-119ms. Troquei de um lado para o outro várias vezes, certificando-me de que não era algum processo que apenas começou.
No entanto, quando removi o foo e a instrução if, o for foi 30 ms mais rápido (foreach foi de 88 ms e for foi de 59 ms). Ambos eram conchas vazias. Estou assumindo que o foreach realmente passou uma variável onde o for estava apenas incrementando uma variável. Se eu adicionar
int foo = intList[i];
Em seguida, a velocidade de for ficou lenta em cerca de 30ms. Estou assumindo que isso teve a ver com a criação de foo e pegando a variável na matriz e atribuindo-a a foo. Se você acessar apenas intList [i], você não terá essa penalidade.
Com toda a honestidade ... Eu esperava que o foreach fosse um pouco mais lento em todas as circunstâncias, mas não o suficiente para importar na maioria das aplicações.
editar: aqui está o novo código usando as sugestões de Jons (134217728 é o maior int que você pode ter antes que a exceção System.OutOfMemory seja lançada):
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();
}
E aqui estão os resultados:
Gerando dados. Calculando o loop: 2458ms Calculando o loop foreach: 2005ms
Trocá-los para ver se lida com a ordem das coisas produz os mesmos resultados (quase).