22

カスタム オブジェクトの Array.Sort と LINQ の並べ替えを比較する簡単なテスト アプリケーションを作成しました。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 秒以上!

すべての配列は並べ替えられます (LINQ は新しいコレクションを生成し、元の配列は並べ替えられません) が、Array.Sort は非常に遅いです! どのように説明できますか?(DEBUG および RELEASE モードでは Array.Sort は極端に失敗します)

Array.Sortでソートする際にラムダ式のコードを貼り付けたのですが、付けても付けなくても同じです。(クラス Person は IComparable インターフェイスを実装します)

4

4 に答える 4

56

結果が得られないため、Linq クエリは実行されません。これは遅延実行と呼ばれます。クエリは、実際に結果を列挙するときにのみ実行されます。

などを使用var results = sort.ToArray()してクエリを実行すると、より正確な結果が得られます。

于 2012-04-24T14:00:31.810 に答える
14

LINQ は怠惰です。あなたpeople2は実際にはソートされていません。LINQ は、ソートされる一時的な「promise オブジェクト」を作成しただけです。実際にそれを実現するにはConsole.WriteLine、ソート結果による評価を強制するか、リスト/配列に変換するか、このようなことを行う必要があります。

詳しくは、遅延実行を参照してください。

于 2012-04-24T14:01:19.263 に答える
9

Linq ステートメントの returnIEnumerable<T>またはフレーバー、this (またはキーワードを使用するもの) は、反復yield時にのみ実行されます。Linq ライブラリ (すべてではない) から利用できるほとんどのアクションは、 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();
于 2012-04-24T14:01:48.220 に答える
1

この部分を変更して、もう一度テストを行ってください。

    start = DateTime.Now;
    var sort = (from s in people2
               orderby s.Age
               select s).ToList();
    end = DateTime.Now;

これにより、LINQ 式が評価されます。

于 2012-04-24T14:09:07.183 に答える