Add
出于某种原因,对 a的操作似乎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 question 的扩展。
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;
}
更新:内部测试表明,大的性能差异仅发生在 x64 版本的 .NET 框架上。使用 32 位版本的框架 Contains 似乎以相同的速度运行(事实上,在某些测试运行中,带有 contains 的版本似乎运行速度慢了一个百分点)在 X64 版本的框架上,带有 contains 的版本似乎运行速度快约 15%。