3

私は現在、独自の要素の大規模なセットを管理する必要があるプロジェクトに取り組んでいます。各要素には最大 20 個のプロパティがあり、すべての要素にはパブリック プロパティ DateTime があります。

プロパティ DateTime は一意ではないため、一般的な辞書を使用してデータを保存することはできません。

現在、これらの要素を ObservableCollection に入れていますが、コレクションから要素を削除するパフォーマンスは非常に遅く、25.000 要素のコレクションから 7000 要素を削除するのに 20 秒ほどかかります。

(検索操作は非常に効率的であるようです。300.000 個の要素のソートされていないコレクションからランダムに選択された 80 個の要素を見つけるのに、わずか 30 ミリ秒しかかかりません)。

各要素は、DateTime.GetHashCode() を返すだけで GetHashCode() メソッドを実装します。

ObservableCollection ではなく HashSet を使用すると、パフォーマンスがかなり向上すると思いましたが、まったく効果がないようです...

そして、一般的な辞書を使用するのはさらに悪いです...

要素に「適切な」ハッシュ関数がある場合 (同じハッシュ コードを持つ要素はほとんどありません)、HashSet は ObservableCollection よりも強力ではありませんか??

4

3 に答える 3

3

オブジェクトのEqualsメソッドをオーバーライドする必要があります。

HashSetは内部IEqualityComparerインスタンスを使用するため、通常は最初に (null) をチェックし、次にオーバーライドされたEqualsメソッドを使用して「null 以外」の項目を別の項目と比較します。

class MyObject
{
    public Guid Id { get; set; }

    public override bool Equals(object other)
    {
        if (other is MyObject)
        {
            // use the 'Id' property as identifier

            MyObject myObj = (MyObject)obj;
            return myObj.Id == this.Id;
        }

        // is not a 'MyObject' based object
        return base.Equals(other);
    }
}

オブジェクトと比較可能な文字列またはその他の種類のオブジェクトを使用することもできます。

編集:

したがって、 OberservableCollectionの代わりに HashSet を使用できます。コレクションが変更されるたびに (追加、削除、クリア、挿入など)、PropertyChangedイベントとCollectionChangedイベントが発生するため、通常、最後のコレクション タイプは処理が遅くなります。

于 2012-05-20T18:27:29.080 に答える
2

マルセルの答えは正しいですが、パフォーマンスが本当に重要な場合は、equals メソッドを少し改善できます。

class MyObject
{
    public Guid Id { get; set; }

    public override bool Equals(object other)
    {
        MyObject myObj = obj as MyObject;

        if (myObj != null)
        {
            // use the 'Id' property as identifier
            return myObj.Id == this.Id;
        }

        // is not a 'MyObject' based object
        return base.Equals(other);
    }
}

このアプローチを使用すると、オブジェクトが特定の型であるかどうかを 1 回だけ呼び出して高速な null チェックを実行することで、コストのかかる関数を 2 回チェックすることを回避できます。詳細については、Eric のこの記事を参照してください。

于 2012-05-24T07:38:25.493 に答える
2

ObservableCollection変更通知を減らすことで、 のパフォーマンスを最適化できます。ItemCollection更新メカニズム ( BeginUpdate/ EndUpdate)を備えたカスタム コレクション クラス を作成しました。

  ItemCollection<Customer> customers = new ItemCollection<Customer>
  customers.BeginUpdate();
  customers.Add( new Customer( "Joe", "Smith" ) );
  customers.Add( new Customer( "Mary", "Jones" ) );
  customers.Add( new Customer( "Lisa", "Black" ) );
  customers.Add( new Customer( "Peter", "Brown" ) );
  customers.EndUpdate();

ソース コード付きの記事: XAML ベースのアプリケーションのプレゼンテーション パターン

于 2012-05-24T07:20:30.727 に答える