哪个更快:Union 还是 Concat?

21

11
尝试两种方式,拿出秒表,然后你就会知道。基于“猜测”的性能“分析”,即使再有经验,也无法作为做出“工程”决策的实质依据。请进行实际测试。 - Eric Lippert
3个回答

56

Union可以删除重复项,而Concat则不会。

因此,如果源中存在任何重复项或内部存在任何重复项,则它们会产生不同的结果。

如果您可以保证不存在重复项,或者只有很少的重复项且您不关心它们是否存在于输出中,Concat将更快,因为无需针对已经生成的每个值测试它们。

但是,如果有许多重复项并且您不需要它们,则Union中额外的处理以删除重复项可能会被您消耗结果的代码的节省所抵消。


10

你只关心执行速度吗?当你收到元素时,你需要多长时间来处理它?

Concat更简单-它不需要执行任何处理,也不需要缓冲已返回的结果。然而,如果交集中有任何元素,它将产生更多结果。如果你需要花费较长时间处理每个结果,则Concat可能会实际上变得更慢。


在我的情况下,我会在最后使用Distinct(),这更倾向于使用Union。 - Jader Dias
6
如果你使用 Union,那么你不需要事后再调用 Distinct。 - Jon Skeet
2
Union会在列表之间删除重复项,但是如果第一个列表本身有重复项,则这些重复项不会被Union删除。因此,根据情况,仍然可能需要调用Distinct。 - Amy B
12
@DavidB:那不是真的(我不确定是否曾经是)。Union将删除重复项,即使它们仅在两个列表中的一个中重复。 - Tim Schmelter
@TimSchmelter,确认!(通过快速控制台应用程序) :) - nurchi

3
上面的说法是正确的。下面是针对某些特殊情况的小补充:
如果您需要连接两个列表,并且需要完全的速度,请考虑使用yield。当然,这远不如Linq中的Union或Concat灵活和舒适。因此,它只在特殊情况下才有意义。
例如,此属性将提供与List1.Concat(List2)相同的结果。
public IEnumerable<MyObject> AllObjects
{
    get
    {
        foreach (MyObject o1 in List1)
            yield return o1;

        foreach (MyObject o2 in List2)
            yield return o2;
    }
}

Concat 正是按照你在示例中展示的方式执行(参见:来源)。因此,没有必要自己实现它。 - scher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接