3

同じタイプのオブジェクトを含む2つのコレクションがあり、両方のコレクションにはそれぞれ約40Kのオブジェクトがあります。

各コレクションに含まれるオブジェクトのコードは、equals関数とhash関数をオーバーライドしたことを除けば、基本的に辞書に似ています。

public class MyClass: IEquatable<MyClass>
{
    public int ID { get; set; }
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        return obj is MyClass && this.Equals((MyClass)obj);
    }

    public bool Equals(MyClass ot)
    {
        if (ReferenceEquals(this, ot))
        {
            return true;
        }

        return 
         ot.ID.Equals(this.ID) &&
         string.Equals(ot.Name, this.Name, StringComparison.OrdinalIgnoreCase); 
    }

    public override int GetHashCode()
    {
         unchecked
         {
             int result = this.ID.GetHashCode();
             result = (result * 397) ^ this.Name.GetSafeHashCode();
             return result;
         }
    }
}

コレクションを比較して違いを取得するために使用しているコードは、PLinqを使用した単純なLinqクエリです。

ParallelQuery p1Coll = sourceColl.AsParallel();
ParallelQuery p2Coll = destColl.AsParallel();

List<object> diffs = p2Coll.Where(r => !p1Coll.Any(m => m.Equals(r))).ToList();

これだけ多くのオブジェクトを比較するより速い方法を知っている人はいますか?現在、クアッドコアコンピューターでは約40秒+/-2秒かかります。データに基づいてグループ化を行い、データの各グループを並行して比較する方がおそらく速いでしょうか?名前に基づいて最初にデータをグループ化すると、約490の一意のオブジェクトになり、最初にIDでグループ化すると、約622の一意のオブジェクトになります。

4

2 に答える 2

15

にないすべてのアイテムを提供するExceptメソッドを使用できます。p2Collp1Coll

var diff = p2Coll.Except(p1Coll);

更新(いくつかのパフォーマンステスト):

免責事項:

実際の時間は、複数の要因(コレクションのコンテンツ、ハードウェア、マシンで実行されているもの、ハッシュコードの衝突の量など)によって異なります。そのため、複雑さとBig O表記があります(DanielBrücknerのコメントを参照)。

これが私の4年前のマシンでの10回の実行のパフォーマンス統計です。

Median time for Any(): 6973,97658ms
Median time for Except(): 9,23025ms

私のテストのソースコードは要点で入手できます。


更新2:

最初のコレクションと2番目のコレクションの両方から異なるアイテムが必要な場合は、実際に両方でExpectを実行する必要あり、その結果は次のようになります。

var diff = p2Coll.Except(p1Coll).Union(p1Coll.Except(p2Coll));
于 2013-01-08T18:21:58.100 に答える
0

交わる

int[] id1 = { 44, 26, 92, 30, 71, 38 };
int[] id2 = { 39, 59, 83, 47, 26, 4, 30 };

IEnumerable<int> both = id1.Intersect(id2);

foreach (int id in both)
    Console.WriteLine(id);

/*
This code produces the following output:

26
30
*/
于 2013-01-08T18:24:01.267 に答える