2012-05-17 20 views
6

C#汎用ハッシュセット< T>検索のパフォーマンスはO(1)、ObservableCollectionの検索のパフォーマンスはO(n)でなければなりません。C#HashSet <T>(ObservableCollectionと比較して)<T>?

私は大量の一意の要素を持っていますが、各要素には一意ではないDateTimeプロパティがあります。

各要素は、単純にDateTime.GetHashCode()を返すことによってHashCodeを計算します。

今、データのサブセットを取得したいとします。私は300.000要素のコレクションにこのLINQクエリを実行する場合は2012年3月と2012年6月

var result = from p in this.Elements 
       where p.Date >= new DateTime(2012, 03, 01) && 
         p.Date <= new DateTime(2012, 30, 06 
       select p; 

の間で日付を持っているすべての要素、それは与えられた範囲内にある80個の要素を返すために〜25ミリ秒かかります - HashSet < T>またはObservableCollection < T>を使用するかどうかは関係ありません。

すべての要素を手動でループしてチェックすると、〜25 msという同じ時間がかかります。

しかし、私は、指定された範囲内のすべての日付のHashCodeを知っています。私のHashSet < T>から、指定されたHashCodesを持つすべての要素を取得することは可能ですか?私はそれがはるかに速くなると思う...

LINQクエリをスピードアップすることは可能ですか?私はそれが私のHashSetの特別な能力を利用しないと仮定します< T>?

+0

各要素のハッシュコードはその日付ですか? – Jodrell

+0

HashSet には、日付が範囲内にある要素を効率的に取得できる特殊な機能はありません。 HashSetを使用すると、特定のオブジェクトまたは値がセット内にあるかどうかを迅速に判断できます。 – hatchet

+0

私の最初の観察は、オブジェクトが異なる場合に可能な限りハッシュコードが異なるはずです(これは必ずしも当てはまるとは限りませんが、あなたが目指すものです)。あなたの場合、これはそうではありません。同一のハッシュコードを持つ異なる要素がありますが、それらは悪いです。最悪の場合、3つのユニークな日付しかない場合、ハッシュセットは3つのバケットしか持たないので、ハッシュセットで何かを見つけると、そのバケット内のすべての要素をソートしてO(n) )。また、これは一般的なメモであり、質問に直接関係していないことに注意してください:) – Chris

答えて

4

ハッシュセットは、指定されたハッシュがセットに含まれているかどうかを判断する上で非常に効率的です。あなたのクエリは、ハッシュセットがIEnumerableを実装してセット全体を反復処理し、日付比較を行うという事実を使用します。ハッシュはまったく使用されません。このため、手動の方法ではクエリと同じ時間がかかるのです。

ハッシュセットのハッシュに基づいて要素を取得することはできません。セット内の要素の存在のみをテストできます。辞書は、あなたがそれを入手する必要がある場合には、あなたが望むものです(そうは思われません)

あなたのデータで何が必要なのかを決定し、そのために最適化された構造を使用してください。これは、複数の内部構造を維持する独自のクラスで、それぞれが効率的であるもの(範囲を検索するものと、複数のフィールドによる存在をチェックするものなど)、または必要に応じて既存の構造が存在する可能性があります。しかし、あなたのデータで何をしたいのかを知らなくても、アドバイスは困難です。

他に考慮すべき点は、あなたが時期尚早に最適化しているかどうかです。手動で検索するのに25msが十分に速ければ、おそらくIEnumerableを実装する任意の構造体で十分です。この場合、必要な他の基準に基づいて1つを選択することができます。

+0

ありがとうございました。私は、現在の検索パフォーマンスが十分であると思っています。私は、ハッシュコードで要素を直接取得することは可能であると考えていました。 'HashSet 'のRemoveメソッドは、通常のコレクションで提供されているものよりもはるかにパフォーマンスが良いので、私は間違いなくHashSetを使用します。 – Ehssan

4

あなたは正しいデータ構造を使用していません。ソートされたリスト(Dateプロパティでソートされている)のようなものを使用する必要があります。そこで、範囲の始めと終わりをバイナリ検索できます。

+2

またはバイナリ検索ツリー:) – undefined

+0

はい、私は間違いなくSortedListまたはSortedDicionaryを使用しますが、私はできません - 要素の 'Date'は一意のキーではありません... – Ehssan

+0

@EhssanDoustなぜ、ユニークであることはあなたが辞書を使用するのをやめさせるでしょEqualsメソッドが2つのインスタンスが等しく、gethashcodeが2つの異なるオブジェクトに対して同じ値を返すとき、それらのオブジェクト間の等価も真である場合、正しく決定する限り、それは機能します。 –

関連する問題