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