我快速测试应用程序,将LINQ排序与我的自定义对象上的Array.Sort进行比较。 Array.Sort似乎非常慢!
我制作了这样的自定义类:
class Person : IComparable<Person>
{
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 SECONDS!
所有数组都已排序(LINQ生成新集合并保留未分类的oryginal数组)但Array.Sort非常慢!怎么解释? (在DEBUG和RELEASE模式下,Array.Sort极度失败)
在使用Array.Sort进行排序时,我使用lambda表达式粘贴了代码,但无论有没有,它都是相同的。 (Class Person实现IComparable接口)
答案 0 :(得分:56)
您的Linq查询甚至没有被执行,因为您没有得到结果。这叫做deferred execution。只有在实际枚举结果时才会执行查询。
使用类似var results = sort.ToArray()
的内容来执行查询,然后您将获得更准确的结果。
答案 1 :(得分:14)
LINQ很懒。你的people2
实际上没有被排序,LINQ只是创建了一个临时的“promise对象”,它将排序。为了实现它,你必须通过Console.WriteLine
强制评估排序结果,将其转换为列表/数组或做其他任何事情。
查看更多:deferred execution。
答案 2 :(得分:9)
Linq语句返回IEnumerable<T>
或者这些(或使用yield
关键字的任何东西)只在迭代时执行。 Linq库(不是全部)are lazy / deferred提供了大多数操作。
你没有迭代它,所以你实际上并没有进行排序。
您需要强制进行完整的迭代。将结果粘贴到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();
答案 3 :(得分:1)
尝试更改此部件并再次进行测试。
start = DateTime.Now;
var sort = (from s in people2
orderby s.Age
select s).ToList();
end = DateTime.Now;
这将评估LINQ表达式。