2012-02-20 109 views
5

次のスニペットが期待した結果を得られないのはなぜですか?小さすぎないランダム配列をソートし、3つの異なるメソッドを使用します。私はそう出てくるスピードを期待していた。.NET 4.0ではArray.Sort()はどうなりましたか? TrySZSort()は削除されましたか?

  1. のArray.sort() - 最速のネイティブTrySZSort機能を使って、私は、カスタム比較演算子クラス
  2. を使用してソートを降順.NET 2.0
  3. から思い出して
  4. ラムダ式ソート。

コード:

class DescComparer : IComparer<double> { 
    // simple comparison 
    // (yes, its not exactly correct ...) 
    public int Compare(double x, double y) { 
     return (x > y) ? -1 : 1; 
    } 
} 
static void Main(string[] args) { 
    Stopwatch sw = new Stopwatch(); 
    Random rand = new Random(); 
    DescComparer comparer = new DescComparer(); 
    double[] a = new double[1000000]; 
    for (int r = 0; r < 20; r++) { 

     // init array 
     for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble(); 
     sw.Restart(); 
     Array.Sort(a); 
     sw.Stop(); 
     Console.WriteLine("ascending took: {0} ms ", sw.ElapsedMilliseconds); 

     // init array 
     for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble(); 
     sw.Restart(); 
     Array.Sort<double>(a, comparer); 
     sw.Stop(); 
     Console.WriteLine("descending took: {0} ms ", sw.ElapsedMilliseconds); 

     // init array 
     for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble(); 
     sw.Restart(); 
     Array.Sort<double>(a, (x,y) => -x.CompareTo(y)); 
     sw.Stop(); 
     Console.WriteLine("desc lambda took: {0} ms ", sw.ElapsedMilliseconds); 

    } 
    Console.Read(); 
} 

しかし、不思議なこと、それは次のようになります:

ascending took: 514 ms 
descending took: 537 ms 
desc lambda took: 915 ms 
ascending took: 511 ms 
descending took: 492 ms 
desc lambda took: 923 ms 
ascending took: 511 ms 
descending took: 483 ms 
desc lambda took: 912 ms 
ascending took: 511 ms 
descending took: 485 ms 
desc lambda took: 914 ms 
ascending took: 518 ms 
descending took: 485 ms 
desc lambda took: 924 ms 
... a.s.o. ... 

ので、ラムダは本当に最も遅いです。しかし、どのように、平らな上昇Array.Sortはもはや高速ではありませんか?これは、Array.Sort(T []、Comparer)が改良されたか、単にTrySZSortが削除されたためですか?それとも私は何かが恋しい?

(リリースビルド、デバッグなし、現在はリフレクタはご利用いただけません))ありがとうございます!

更新日: @Reed Copseyのヒントによれば、ラムダ式は公平ではありません。私はそれをcomparerと同じように変更しようとしました。スピードが上がった。アスキー/ラムダは55%から75%を超えました。だからそれはまだかなり遅いです。

+1

私は、パフォーマンスの結果を説明することはできませんが、反射鏡を見てから、TrySZSortがなくなっていない、と 'Sort'と'ソートの両方のために呼ばれています 'メソッドではなく、comparerがnullまたはdefaultの場合のみです。 –

+0

@ Meta-Knight hm。面白い!それで、マネージドサイドが少しずつ立ち上がりました。伝えてくれてありがとう! –

+1

はい、Array.Sort()は.NET 4で書き直されました。いくつかのソーターがあります。あなたは、比較者が誤った行動をしたときに無限ループに陥ることのないものを手に入れているかもしれません。参照元から入手可能なコメント付きのソースコードを見て、それを見てください。 –

答えて

5

したがって、ラムダは実際には最も遅いです。しかし、どのように、平らな上昇Array.Sortはもはや高速ではありませんか?これは、Array.Sort(T []、Comparer)が改良されたか、単にTrySZSortが削除されたためですか?それとも私は何かが恋しい?

ここには2つの問題があります。まず、これは本当にあなたのビルドとシステムに依存 -

私のシステムでは、x64の中で、Array.Sort()最速で、かなりの量によって:x86で

ascending took: 192 ms 
descending took: 248 ms 
desc lambda took: 326 ms 
ascending took: 194 ms 
descending took: 247 ms 
desc lambda took: 326 ms 

、物事は少し異なっている - しかし、

ascending took: 235 ms 
descending took: 223 ms 
desc lambda took: 325 ms 
ascending took: 234 ms 
descending took: 222 ms 
desc lambda took: 325 ms 

これらのタイミングを実行したときにビジュアルスタジオのホストがアタッチされましたか? VS内で実行すると、リリースビルドさえ劇的に遅くなります(つまり、デフォルトでCtrl + F5ではなくF5)。


ラムダに関しては、完全に公平ではないことにも注意してください。あなたはされるであろう、テストのために同じメカニズムを使用する必要があります。

Array.Sort<double>(a, (x, y) => (x > y) ? -1 : 1); 
+0

右。ラムダ(X86)との差はあまり重要ではない。しかし、ラムダなしの速度比asc/descはほぼ同じです:5%。 –

関連する問題