在查看ANTS分析器时,FirstOrDefault比SingleOrDefault快得多

时间:2013-05-20 19:03:07

标签: c# linq

我有一个包含5000多个项目的通用集合。所有项目都是唯一的,因此我使用SingleOrDefault从集合中提取项目。今天我使用Red Gate ANTS分析器来查看代码,发现我的SingleOrDefault调用有5000万次点击达到1800万次(~3.5秒),而当我将它改为FirstOrDefault时,它有9百万次击中(~1.5秒)。

我使用了SingleOrDefault,因为我知道集合中的所有项目都是唯一的。

编辑:问题是为什么FirstOrDefault比SingleOrDefault更快,即使这是我们应该使用SingleOrDefault的确切场景。

5 个答案:

答案 0 :(得分:6)

如果有多个,

SingleOrDefault()会引发异常。为了确定这一点,它必须验证不超过一个。

另一方面,FirstOrDefault()一旦找到,就会停止查看。因此,在许多情况下,我希望它会快得多。

答案 1 :(得分:3)

SingleOrDefault(predicate)确保最多只有一个项与给定的谓词匹配,因此即使它在集合的开头附近找到匹配项,它仍然必须继续到{{1}的末尾}。

IEnumerable在找到集合中的匹配项后立即停止。如果您的“第一次匹配”在FirstOrDefault(predicate)中均匀分布,那么您平均必须经历IEnumerable的一半。

对于一系列IEnumerable项,N将运行您的谓词SingleOrDefault次,N将运行您的谓词(平均)FirstOrDefault次。这解释了为什么您看到N/2的“点击次数”是SingleOrDefault的两倍。

如果您知道,您将只有一个匹配的项目,因为您和您的系统控制了您的收藏来源,那么您最好使用FirstOrDefault 。例如,如果您的收藏来自用户,那么使用FirstOrDefault作为对用户输入的检查是有意义的。

答案 2 :(得分:1)

FirstOrDefault将在第一次点击时返回。 SinglerOrDefault不会在第一次点击时返回,但也会查看所有其他元素以检查它是否唯一。因此,在大多数情况下,FirstOrDefault会更快。如果您不需要进行唯一性检查,请参阅FirstOrDefault。

答案 3 :(得分:1)

我非常怀疑SingleOrDefaultFirstOrDefault之间的选择将成为您的瓶颈。我认为分析工具有望突出更大的鱼类。您自己的指标显示,对于任何给定的迭代,这相当于几乎无法辨认的时间单位。

但我建议使用符合期望的那个。即,是否有多个匹配谓词错误?如果是,请使用强制执行该期望的方法。 SingleOrDefault。 (同样,如果 none 也是错误,只需使用Single。)如果不是多个错误,请随意使用First变体,代替。

现在应该明白为什么一个人可能比另一个人略快,正如其他答案所讨论的那样。一个是强制执行约束,当然这是通过执行逻辑来完成的。另一个不强制执行该特定约束,因此不会因此而延迟。

答案 4 :(得分:0)

我使用LinqPad运行测试,表明使用Single和SingleOrDefault的查询比使用First或FirstOrDefault的查询更快。这些测试是针对大型数据集的相当简单的查询(不涉及连接)。我没想到这是结果,实际上我试图向另一个开发人员证明我们应该使用First和FirstOrDefault,但是当证据表明Single实际上更快时,我的论证基础就消失了。可能存在First更快的情况,但不要认为它是一揽子情况。

相关问题