Łatwy test do pół-walidacji. Zrobiłem mały test, żeby zobaczyć. Oto kod:
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();
}
A oto sekcja dla wszystkich:
foreach (int i in intList)
{
int foo = i * 2;
if (foo % 2 == 0)
{
}
}
Kiedy wymieniłem for na foreach - foreach był o 20 milisekund szybszy - konsekwentnie . Dla było 135-139 ms, podczas gdy foreach było 113-119 ms. Kilka razy zamieniałem się tam iz powrotem, upewniając się, że to nie jakiś proces właśnie się rozpoczął.
Jednak gdy usunąłem instrukcję foo i if, for było szybsze o 30 ms (foreach to 88 ms, a for było 59 ms). Obie były pustymi muszlami. Zakładam, że foreach faktycznie przekazał zmienną, gdzie jako for po prostu zwiększał zmienną. Jeśli dodałem
int foo = intList[i];
Następnie for stają się wolne o około 30 ms. Zakładam, że miało to związek z utworzeniem foo i pobraniem zmiennej w tablicy i przypisaniem jej do foo. Jeśli uzyskasz dostęp do intList [i], nie będziesz mieć tej kary.
Szczerze mówiąc ... Spodziewałem się, że foreach będzie nieco wolniejsze we wszystkich okolicznościach, ale nie na tyle, aby miało to znaczenie w większości zastosowań.
edit: oto nowy kod wykorzystujący sugestie Jonsa (134217728 to największe int, jakie możesz mieć przed wyrzuceniem wyjątku 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();
}
A oto wyniki:
Generowanie danych. Obliczanie dla pętli: 2458 ms Obliczanie każdej pętli: 2005 ms
Zamiana ich miejsc, aby zobaczyć, czy zajmuje się kolejnością rzeczy, daje takie same wyniki (prawie).