【发布时间】:2017-03-25 12:16:33
【问题描述】:
我只是做了一些优化,对此感到困惑。
我的原始代码如下所示:
HashSet<IExampleAble> alreadyProcessed;//a few million items
void someSetRoutineSlower(HashSet<IExampleAble> exampleSet)
{
foreach (var item in exampleSet)
{
if (!alreadyProcessed.Contains(item))
{
// do Stuff
}
}
}
这需要大约 120 万个刻度来处理。
然后我用 exceptwith 尝试了同样的方法:
void someSetRoutineFaster(HashSet<IExampleAble> exampleSet)
{
exampleSet.ExceptWith(alreadyProcessed);//doesnt this have to check each item of it's collection against the other one, thus actually looping twice?
foreach (var item in exampleSet)
{
// do Stuff
}
}
它以大约 0.4 万到 0.7 万个滴答声运行。
exceptwith 中进行了哪些优化?它不是也必须像我在第一个 code-sn-p 中那样检查所有项目吗?
【问题讨论】:
-
@harold 发布了看似正确的答案,但他出于某种原因将其删除...
ExceptWith()从集合中删除项目,因此每个删除的元素在搜索下一个元素。使用.Contains(),集合永远不会变小,因此每个元素的搜索时间不会减少。 -
@MatthewWatson 但 exceptwith 迭代完整的其他集合。那是比示例集大得多的数量级。我的第一个想法是避免迭代“已经处理”并在迭代示例集一次时进行包含检查。使用示例集正是我试图避免的,但速度更快
-
@MatthewWatson 我刚刚试了一下,它的速度和使用一样快。还是不明白为什么
-
你能分享你的性能测试吗?
-
请发布包含简单基准的可执行代码。这个版本是没有附加调试器的 x64 版本吗?如前所述,结果是不可能的,因为 alreadyProcessed 要大得多。所以基准在某种程度上是错误的。
标签: c# .net performance optimization