HashSet<T> t = new HashSet<T>();
// add 10 million items
Dictionary<K, V> t = new Dictionary<K, V>();
// add 10 million items.
どっちの.Contains
方が早く戻るの?
明確にするために、私の要件は、データ構造内に存在するかどうかを確認する必要があるオブジェクトが1,000万個(実際には文字列)あることです。私は決して反復しません。
HashSet<T> t = new HashSet<T>();
// add 10 million items
Dictionary<K, V> t = new Dictionary<K, V>();
// add 10 million items.
どっちの.Contains
方が早く戻るの?
明確にするために、私の要件は、データ構造内に存在するかどうかを確認する必要があるオブジェクトが1,000万個(実際には文字列)あることです。私は決して反復しません。
回答:
HashSet vs List vs Dictionaryパフォーマンステスト。ここから取得。
1000000個のオブジェクトを追加します(重複をチェックせずに)
10000のコレクションのオブジェクトの半分のチェックが含まれています
10000のコレクションのオブジェクトの半分を削除します
私はあなたDictionary<TKey, TValue>
が2番目のケースで意味していると思いますか?HashTable
非ジェネリッククラスです。
実際の要件に基づいて、ジョブに適したコレクションを選択する必要があります。あなたが実際に行う必要値に各キーをマップするために?その場合は、を使用してくださいDictionary<,>
。セットとしてのみ気にする場合は、を使用してくださいHashSet<>
。
私は期待HashSet<T>.Contains
してDictionary<TKey, TValue>.ContainsKey
、彼らは基本的に、同じアルゴリズムを使用している-基本的に同じことを実行するために(あなたは賢明に自分の辞書を使用していると仮定すると、同等の操作です)。私は内のエントリと推測Dictionary<,>
あなたがキャッシュを吹いての大きな尤度で終わる大きいことDictionary<,>
よりもHashSet<>
、私は単にあなたがしているものに関してそれは間違ったデータ型を選択するの痛みに比べて微々たるものであることを期待したいです達成しようとしています。
Dictionary
他の理由ですでにを取得している場合は、それを使用する必要があります。
辞書<TKey、TValue>のMSDNドキュメントから
「Dictionaryクラスはハッシュテーブルとして実装されているため、キーを使用した値の取得は非常に高速で、O(1)に近くなります。」
メモ付き:
「検索の速度は、TKeyに指定されたタイプのハッシュアルゴリズムの品質に依存します」
私はあなたの質問/投稿が古いことを知っています-しかし、同様の質問への回答を探している間に私はこれに偶然出会いました。
お役に立てれば。詳細については、[ 備考]セクションまでスクロールしてください。 https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx
これらは異なるデータ構造です。また、の汎用バージョンはありませんHashTable
。
HashSet
キーと値のペアを含むタイプTの値が含まれますHashTable
(またはDictionary
)。したがって、格納する必要のあるデータのコレクションを選択する必要があります。
この質問に対する承認された回答は、質問に有効に回答するものではありません。それはたまたま正しい答えを与えるが、その答えは彼らが提供した証拠によって示されていない。
その答えが示すのは、Dictionary
またはでのキールックアップは、でのルックアップHashSet
よりもはるかに速いということList
です。これは事実ですが、興味深いものでも、驚くべきものでもありませんし、速度が同じであることの証明でもありません。
以下のコードを実行してルックアップ時間を比較しましたが、私の結論は、それらは実際には同じ速度であるということです。(または、少なくとも、何らかの違いがある場合、違いはその速度の標準偏差内に十分あります)
具体的には、このテストでは、1億回のルックアップの両方に10〜11.5秒かかりました。
テストコード:
private const int TestReps = 100_000_000;
[Test]
public void CompareHashSetContainsVersusDictionaryContainsKey()
{
for (int j = 0; j < 10; j++)
{
var rand = new Random();
var dict = new Dictionary<int, int>();
var hash = new HashSet<int>();
for (int i = 0; i < TestReps; i++)
{
var key = rand.Next();
var value = rand.Next();
hash.Add(key);
dict.TryAdd(key, value);
}
var testPoints = Enumerable.Repeat(1, TestReps).Select(_ => rand.Next()).ToArray();
var timer = new Stopwatch();
var total = 0;
timer.Restart();
for (int i = 0; i < TestReps; i++)
{
var newKey = testPoints[i];
if (hash.Contains(newKey))
{
total++;
}
}
Console.WriteLine(timer.Elapsed);
var target = total;
Assert.That(total == target);
timer.Restart();
for (int i = 0; i < TestReps; i++)
{
var newKey = testPoints[i];
if (dict.ContainsKey(newKey))
{
total++;
}
}
Console.WriteLine(timer.Elapsed);
Assert.That(total == target * 2);
Console.WriteLine("Set");
}
}