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

Tom*_*ora 22 c# linq arrays sorting

我做了快速测试应用程序,将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()
    { }

}
Run Code Online (Sandbox Code Playgroud)

然后我在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;
}
Run Code Online (Sandbox Code Playgroud)

之后我测量了按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();
Run Code Online (Sandbox Code Playgroud)

Linq时间:大约1或2毫秒

Array.Sort:超过16 秒!

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

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

Bot*_*000 56

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

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

  • 不执行的代码将始终执行执行代码! (49认同)
  • 我希望OP不会感到愚蠢.这是我见过的非常常见的问题/错误(可能已经完成了自己):当你实际枚举一个IEnumerable并且只是改变它时,不知道或不了解它.我认为比这更常见的是通过多次枚举IEnumerable来降低效率的问题. (8认同)

Ski*_*nok 14

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

查看更多:延迟执行.


Ada*_*rth 9

Linq语句的返回IEnumerable<T>或风格,这个(或使用yield关键字的任何东西)只在迭代它时执行.Linq库(不是全部)提供的大多数操作都是延迟/延迟的.

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

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

var sort = (from s in people2
            orderby s.Age
            select s).ToList();
Run Code Online (Sandbox Code Playgroud)

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

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

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

var s = sort.First();
Run Code Online (Sandbox Code Playgroud)