Rei*_*l-- 2 linq performance ienumerable
从逻辑上讲,以下都是相同的:
var foo = ( A.Union(B).Union(C).Union(D) ).ToList();
var bar = ( A.Union(B.Union(C.Union(D))) ).ToList();
var baz = ( D.Union(C.Union(B.Union(A))) ).ToList();
Run Code Online (Sandbox Code Playgroud)
他们应该在最后返回完全相同的列表.
它们之间有什么区别(如果有的话)?
我猜想唯一的区别是与你在每个集合中迭代的频率有关的性能问题?而这foo并baz再有完全相同的性能-迭代A4倍,但在D只有一次?
是对的吗?
是否有其他有趣的属性可能会引导您关心做一个而不是另一个?
这些解决方案都没有多次迭代它的参数.此外,参数在他们的文字,这是在给定的顺序重复A,B,C,D为foo和bar和D,C,B,A的baz.
您可以使用一个简单的生成器来演示这一点,该生成器在您迭代时打印它返回的项目:
class VisibleIterator : IEnumerable<string> {
private readonly string name;
public VisibleIterator(string name) {
this.name = name;
}
public IEnumerator<string> GetEnumerator() {
for (var i = 0 ; i != 4 ; i++) {
var res = name+i;
Console.WriteLine(res);
yield return res;
}
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
Run Code Online (Sandbox Code Playgroud)
集合未多次枚举的原因是,UnionIterator<T>后面的代码Union<T>保留了已访问过的项的哈希集:
static IEnumerable<TSource> UnionIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer) {
Set<TSource> set = new Set<TSource>(comparer);
foreach (TSource element in first)
if (set.Add(element)) yield return element;
foreach (TSource element in second)
if (set.Add(element)) yield return element;
}
Run Code Online (Sandbox Code Playgroud)
Set<TSource> set内部尺寸可能会导致性能差异很小UnionIterator<T>.每个例子中都会有三个这样的集合 - 每个Union呼叫一个.顶级set总是最终得到Union结果的所有成员.set但是,中级可能会有更多项目或更少项目,具体取决于您合并集合的顺序以及每个集合中相对项目的数量.
| 归档时间: |
|
| 查看次数: |
62 次 |
| 最近记录: |