Я интересовался тем, будет ли это быстрее для сортировки моих классов с помощью LINQ, или путем реализации интерфейса IComparable и Списка. Вид. Я был вполне удивлен, когда код LINQ был быстрее.
Чтобы сделать тест, я сделал очень простой класс с not-so-apt названием TestSort, реализовав IComparable.
class TestSort: IComparable<TestSort> {
private int age;
private string givenName;
public int Age {
get {
return age;
}
set {
age = value;
}
}
public string GivenName {
get {
return givenName;
}
set {
givenName = value;
}
}
public TestSort(int age, string name) {
this.age = age;
this.givenName = name;
}
public int CompareTo(TestSort other) {
return this.age.CompareTo(other.age);
}
}
Затем простая программа для сортировки его много раз - вид был намного более дорогим, чем копирование списка, таким образом, эффект этого может быть проигнорирован.
class Program {
static void Main(string[] args) {
// Create the test data
string name = "Mr. Bob";
Random r = new Random();
var ts2 = new List<TestSort>();
for (int i = 0; i < 100; i++) {
ts2.Add(new TestSort(r.Next(), name));
}
DateTime start, end;
// Test List<>.Sort
start = DateTime.Now;
for (int i = 0; i < 100000; i++) {
var l = ts2.ToList();
l.Sort();
}
end = DateTime.Now;
Console.WriteLine("IComparable<T>: ");
Console.WriteLine((end - start).TotalMilliseconds);
// Test Linq OrderBy
start = DateTime.Now;
for (int i = 0; i < 100000; i++) {
var l = ts2.ToList();
l = l.OrderBy(item => item.Age).ToList();
}
end = DateTime.Now;
Console.WriteLine("\nLINQ: ");
Console.WriteLine((end - start).TotalMilliseconds);
Console.WriteLine("Finished.");
Console.ReadKey();
}
}
Я был вполне удивлен получить следующий вывод:
IComparable<T>:
2965.1696
LINQ:
2181.1248
Иногда LINQ понижался бы 2000, и иногда IComparable будет идти приблизительно 3 000.
Когда я протестировал его с нормальным List<Int>
List.Sort
был 1/4 скоростью LINQ, который остался приблизительно в 2000.
Итак, почему только приблизительно 66% LINQ являются скоростью нормального вида для моего класса? Я делаю что-то не так со своей реализацией IComparable?
Обновление: Я просто думавший попытаться делать его в режиме выпуска, и да, результаты отличался:
IComparable<T>:
1593.0911
Linq:
1958.1119
Но мне все еще очень интересно знать, почему IComparable медленнее в режиме отладки.
Если перед началом измерения вы убедитесь, что все согласовано с JIT, вы можете получить другие результаты (я также рекомендую использовать класс Секундомер
для измерения времени):
var ll = ts2.ToList();
ll.Sort();
ll.OrderBy(item => item.Age).ToList();
Согласно по моим измерениям (после добавления приведенного выше кода) IComparable всегда быстрее (даже при отладке).
Это могут быть накладные расходы на вызов метода CompareTo
, который будет заменен встроенным при компиляции и запуске в режиме выпуска.