c#-Linq OrderBy()与List.Sort()的速度

这是随机整数的枚举:

var r = new Random();
var e = Enumerable.Repeat(1, 10_000_000).Select( _ => r.Next());

您认为哪个版本更快:

var result = e.OrderBy(x => x).Last(); //materialize the IEnumerable

要么

var l = e.ToList();
l.Sort();
var result = l.Last();

我希望第一个示例中的.OrderBy(x => x).Last()是
优化后仅对列表的一小部分进行排序或仅对列表进行O(n)遍历.

扰流板:
不是.

但是,这两个版本的性能至少应该差不多,对吗?我的意思是:

在第一个中,OrderBy()分配一个临时数组并将其排序.
在第二个中,我显式分配了一个列表,并对其进行了Sort()处理.

实际结果表明,OrderBy()示例要慢4-5倍! (5-6秒和1.2-1.3秒)

任何人都可以提出原因的解释吗?

.OrderBy(x => x)情况的确执行其x =>每个元素的x身份lambda.
和…之间的不同:

var result2 = e.Last();

var result2 = e.Select(x=>x).Last();

是可测量的,但很小:在第二种情况下多了30-50 ms.因此,这并不能解释巨大的差距.

解决方法:

列表使用比较器比较类型时似乎使用了special optimized C++ version of sorting.默认值或类型不使用IComparer. OrderBy始终会进行适用于任何类型和IComparer的通用排序.

如果将“选择结果”替换为MyInt类型的对象,如下所示:

public class MyInt : IComparable {
    public int value;
    public MyInt(int newv) => value = newv;

    public int CompareTo(object obj) {
        if (obj is MyInt m2) {
            return value.CompareTo(m2.value);
        }
        else if (obj is int i2) {
            return value.CompareTo(i2);
        }
        else {
            throw new Exception($"can't compare MyInt to {obj.GetType()}");
        }
    }
}

var e = Enumerable.Repeat(1, 10_000_000).Select(_ => new MyInt(r.Next()));

然后,OrderBy将比List.Sort方法快2倍.

注意,如果使用Comparer<> .Create为MyInt创建一个Comparer,则List.Sort与OrderBy差不多:

l.Sort(Comparer<MyInt>.Create((m1,m2) => m1.value.CompareTo(m2.value)));
上一篇:python-在日期时按字典中的值排序


下一篇:java-使用整数和字符进行数组排序