与LINQ相比,为什么Array.Sort()这么慢?

我做了快速测试应用程序,将LINQ排序与我的自定义对象上的Array.Sort进行比较。 Array.Sort似乎非常慢!

我创建了这样的自定义类:

class Person : IComparable { public int Age { get; set; } public string Name { get; set; } public int CompareTo(Person obj) { return this.Age.CompareTo(obj.Age); } public Person() { } } 

然后我在main()中做了我的测试人员:

 string name = "Mr. Tomek"; Random r = new Random(); int size = 10000000; DateTime start, end; 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; } 

之后我测量了按Array.Sort和LINQ排序的时间:

 start = DateTime.Now; var sort = from s in people2 orderby s.Age select s; end = DateTime.Now; Console.WriteLine("LINQ: "); Console.WriteLine((end - start).TotalMilliseconds); start = DateTime.Now; Array.Sort(people1,((Person p1, Person p2)=>{return p1.CompareTo(p2);})); end = DateTime.Now; Console.WriteLine("IComparable: "); Console.WriteLine((end - start).TotalMilliseconds); Console.ReadLine(); 

Linq时间:大约1或2毫秒

Array.Sort:超过16 秒!

所有数组都被排序(LINQ产生新的集合并留下未分类的oryginal数组)但Array.Sort非常慢! 怎么解释? (在DEBUG和RELEASE模式下,Array.Sort极度失败)

在使用Array.Sort进行排序时,我使用lambda表达式粘贴了代码,但无论有没有它都是相同的。 (类Person实现IComparable接口)

您的Linq查询甚至没有执行,因为您没有得到结果。 这称为延迟执行 。 只有在实际枚举结果时才会执行查询。

使用类似var results = sort.ToArray()来执行查询,然后您将获得更准确的结果。

LINQ很懒。 你的people2实际上并没有被排序,LINQ只是创建了一个临时的“promise对象”,它将排序。 要实现它,必须通过Console.WriteLine强制评估排序结果,将其转换为列表/数组或执行其他任何操作。

查看更多: 延迟执行 。

Linq语句返回IEnumerable或其味道,这个(或使用yield关键字的任何东西)仅在迭代时执行。 Linq库(不是全部)提供的大多数操作都是延迟/延迟的 。

你没有迭代它,所以你实际上没有执行排序。

您需要强制完整迭代。 将结果粘贴到List中将完全迭代返回的可枚举:

 var sort = (from s in people2 orderby s.Age select s).ToList(); 

只有这样你才能比较苹果和苹果。

实际上,在排序( orderby )的情况下,只需选择第一个项将导致完整的迭代,因为需要在返回第一个结果之前完全完成排序:

 var sort = from s in people2 orderby s.Age select s; var s = sort.First(); 

尝试更改此部件并再次进行测试。

  start = DateTime.Now; var sort = (from s in people2 orderby s.Age select s).ToList(); end = DateTime.Now; 

这将评估LINQ表达式。