【问题标题】:Why Enumerable.OrderBy<TSource, TKey> Method works faster when it doesn't use Comparer为什么 Enumerable.OrderBy<TSource, TKey> 方法在不使用 Comparer 时工作得更快
【发布时间】:2012-06-24 13:14:22
【问题描述】:

我已经写了排序方法的代码测试速度。它生成一个集合并使用不同的方法对其进行排序。

public void TestMethod1()
    {
        var unsortedCollection = GenerateCollection();

        var toSort = unsortedCollection.ToList();
        Console.WriteLine("OrderBy x.A: " + Measure(() => toSort.OrderBy(x => x.A).ToArray()) + "ms");
        toSort = unsortedCollection.ToList();
        Console.WriteLine("OrderBy x: " + Measure(() => toSort.OrderBy(x => x).ToArray()) + "ms");
        toSort = unsortedCollection.ToList();
        Console.WriteLine("OrderBy x using Comparer: " + Measure(() => toSort.OrderBy(x => x, new Comparer()).ToArray()) + "ms");
        toSort = unsortedCollection.ToList();
        Console.WriteLine("OrderBy x using Comparer<int>.Default: " + Measure(() => toSort.OrderBy(x => x.A, Comparer<int>.Default).ToArray()) + "ms");
        toSort = unsortedCollection.ToList();
        Console.WriteLine("OrderBy x using Comparer<SimpleObject>.Default: " + Measure(() => toSort.OrderBy(x => x, Comparer<SimpleObject>.Default).ToArray()) + "ms");

        toSort = unsortedCollection.ToList();
        Console.WriteLine("Sort: " + Measure(() =>
                                                 {
                                                     toSort.Sort();
                                                     toSort.ToArray();
                                                 }) + "ms"); 
        toSort = unsortedCollection.ToList();
        Console.WriteLine("Sort using Comparison: " + Measure(() =>
                                                                  {
                                                                      toSort.Sort((x, y) => x.A.CompareTo(y.A));
                                                                      toSort.ToArray();
                                                                  }) + "ms");
        toSort = unsortedCollection.ToList();
        Console.WriteLine("Sort using Comparer: " + Measure(() =>
                                                                {
                                                                    toSort.Sort(new Comparer());
                                                                    toSort.ToArray();
                                                                }) + "ms");

    }

   private List<SimpleObject> GenerateCollection()
   {
       int length = 10000000;
       var list = new List<SimpleObject>();
       for (int i=0; i<length; i++)
       {
           list.Add(new SimpleObject());
       }
       return list;
   }

    private long Measure(Action method)
    {
        Stopwatch sw = new Stopwatch();
        sw.Reset();
        sw.Start();
        method();
        sw.Stop();
        return sw.ElapsedMilliseconds;
    }

    public class Comparer: IComparer<SimpleObject>
    {
        public int Compare(SimpleObject x, SimpleObject y)
        {
            return x.A.CompareTo(y.A);
        }
    }
    public class SimpleObject: IComparable<SimpleObject>
    {
    public int A;
    private static Random rand = new Random();
    private const int maxValue = 1000000;

    public SimpleObject()
    {
        A = rand.Next(maxValue);
    }

    public int CompareTo(SimpleObject other)
    {
        return A.CompareTo(other.A);
    }
}

结果如下:

OrderBy x.A: 8732ms
OrderBy x: 19136ms
OrderBy x using Comparer: 17054ms
OrderBy x using Comparer<int>.Default: 8758ms
OrderBy x using Comparer<SimpleObject>.Default: 19817ms
Sort: 8000ms
Sort using Comparison: 9515ms
Sort using Comparer: 8990ms

我想知道为什么 OrderBy 使用 Comparer 的工作时间比不使用 Comparer 的时间长,以及为什么使用比较的排序比使用 Comparer 的工作时间更长。

【问题讨论】:

  • 它解释了 OrderBy 和 Sort 之间的区别,但没有解释为什么使用自定义 Comparer 需要很多时间。
  • Sort 重载之间的差异并不显着,但 OrderBy 重载之间的差异更令人感兴趣。如果您不提供比较器,则使用以下比较器:(IComparer&lt;TKey&gt;) Comparer&lt;TKey&gt;.Default。如果您明确指定此比较器,事情会如何叠加?
  • 您是否尝试过通过分析器运行它?恕我直言,这是真正说出这里发生的事情的唯一方法(除了使用某种形式的反编译器)

标签: c# linq enumerable


【解决方案1】:

这似乎是对象比较的问题。 OrderBy 方法缓存键。 int 键比较快,对象键比较长。

【讨论】:

    猜你喜欢
    • 2012-08-14
    • 1970-01-01
    • 2012-05-29
    • 2021-07-20
    • 2014-03-03
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2014-11-03
    相关资源
    最近更新 更多