何らかの理由で、 要素が に既に存在する場合の操作よりも、 でのAdd
操作のHashSet
方が遅いようです。Contains
HashSet
ここに証拠があります:
Stopwatch watch = new Stopwatch();
int size = 10000;
int iterations = 10000;
var s = new HashSet<int>();
for (int i = 0; i < size; i++) {
s.Add(i);
}
Console.WriteLine(watch.Time(() =>
{
for (int i = 0; i < size; i++) {
s.Add(i);
}
}, iterations));
s = new HashSet<int>();
for (int i = 0; i < size; i++) {
s.Add(i);
}
// outputs: 47,074,764
Console.WriteLine(watch.Time(() =>
{
for (int i = 0; i < size; i++) {
if (!s.Contains(i))
s.Add(i);
}
}, iterations));
// outputs: 41,125,219
既存の要素Contains
よりも速いのはなぜですか?Add
注:Stopwatch
別の SO の質問からこの拡張機能を使用しています。
public static long Time(this Stopwatch sw, Action action, int iterations) {
sw.Reset();
sw.Start();
for (int i = 0; i < iterations; i++) {
action();
}
sw.Stop();
return sw.ElapsedTicks;
}
更新: 内部テストにより、大きなパフォーマンスの違いは .NET フレームワークの x64 バージョンでのみ発生することが明らかになりました。フレームワークの 32 ビット バージョンでは、Contains を追加するのと同じ速度で実行されるように見えます (実際、contains を含むバージョンは、一部のテスト実行でパーセント遅く実行されるようです)。フレームワークの X64 バージョンでは、contains を含むバージョンは約 15% 速く実行されます。