Chciałem sprawdzić co jest wydajniejsze, LINQ czy użycie IComparera.
Odpowiedź: "to zależy?"
Na początek zrobiłem małą klasę obiektu do testowania, która wyglądała tak:
Następnie w głównej pętli programu napisałem następujący kod:
static void Main(string[] args)
{
string name = "Mr. Tomek";
Random r = new Random();
int size = 50;
Stopwatch stopWatch = new Stopwatch();
while (size < 1000000)
{
int linqTime = 0;
int sortTime = 0;
int repeats = 10;
Console.WriteLine("Size = {0}", size);
for (int a = 0; a < repeats; ++a)
{
Person[] people1 = new Person[size];
Person[] people2 = new Person[size];
for (int i = 0; i < size; i++)
{
people1[i] = new Person();
people1[i].Age = r.Next(0, 10000);
people1[i].Name = name;
people2[i] = new Person();
people2[i].Age = people1[i].Age;
people2[i].Name = people1[i].Name;
}
stopWatch.Start();
Array.Sort(people1);
stopWatch.Stop();
sortTime += (int)stopWatch.ElapsedMilliseconds;
stopWatch.Start();
var sort = from p in people2
orderby p.Age
select p;
var x = sort.ToArray();
//Console.WriteLine(x[0].Name + " " + x[0].Age);
stopWatch.Stop();
linqTime += (int)stopWatch.ElapsedMilliseconds;
}
Console.WriteLine("IComparable: {0}", sortTime/repeats);
Console.WriteLine("LINQ: {0}", linqTime/repeats);
Console.WriteLine();
size += size;
}
Console.WriteLine("Measurments done");
Console.ReadLine();
}
Tworzone są kolejno 2 tablice z losowymi wartościami "Age" dla każdego obiektu person a następnie sortowane przy pomocy LINQ i Array.Sort wykorzystująca IComparer.Okazało się że wydajność LINQ i Array.Sort zależała od tego, co było wcześniej!
Obie metody pracowały prawie tak samo długo, lecz sortowanie, które było pierwsze w kodzie (w tym przypadku sortowanie przy pomocy IComparera) przebiegało szybciej!
Jeśli by zamienić miejscami bloki kodu odpowiadające za sortowanie LINQ i Array.Sort:
stopWatch.Start();
var sort = from p in people2
orderby p.Age
select p;
var x = sort.ToArray();
//Console.WriteLine(x[0].Name + " " + x[0].Age);
stopWatch.Stop();
linqTime += (int)stopWatch.ElapsedMilliseconds;
stopWatch.Start();
Array.Sort(people1);
stopWatch.Stop();
sortTime += (int)stopWatch.ElapsedMilliseconds;
okazałoby się, że tym razem nieznacznie wygrywało LINQ!
Wszystko stało się jasne, gdy dopisałem parę linijek kodu zapisującego wyniki do pliku CSV i wygenerowałem wykresy w Excelu:
Porównanie czasu sortowania:
Stosunek czasów sortowania LINQ / IComparer


Jednak nie potrafię wyjaśnić czemu tak się dzieje...



Brak komentarzy:
Prześlij komentarz