gpt4 book ai didi

c# - 为什么 LINQ .Where(predicate).First() 比 .First(predicate) 快?

转载 作者:IT王子 更新时间:2023-10-29 03:42:35 24 4
gpt4 key购买 nike

我正在做一些性能测试并注意到像这样的 LINQ 表达式

result = list.First(f => f.Id == i).Property

result = list.Where(f => f.Id == i).First().Property

这似乎违反直觉。我原以为第一个表达式会更快,因为它可以在满足谓词后立即停止遍历列表,而我原以为 .Where() 表达式可能遍历在对结果子集调用 .First() 之前整个列表。即使后者确实短路,也不应该比直接使用 First 快,但确实如此。

下面是两个非常简单的单元测试来说明这一点。在 TestWhereAndFirst 上进行优化编译时,比 .Net 和 Silverlight 4 上的 TestFirstOnly 快大约 30%。我尝试使谓词返回更多结果,但性能差异是相同的。

谁能解释为什么 .First(fn).Where(fn).First() 慢?与 .Where(fn).Count() 相比,我看到 .Count(fn) 有类似的反直觉结果。

private const int Range = 50000;

private class Simple
{
public int Id { get; set; }
public int Value { get; set; }
}

[TestMethod()]
public void TestFirstOnly()
{
List<Simple> list = new List<Simple>(Range);
for (int i = Range - 1; i >= 0; --i)
{
list.Add(new Simple { Id = i, Value = 10 });
}

int result = 0;
for (int i = 0; i < Range; ++i)
{
result += list.First(f => f.Id == i).Value;
}

Assert.IsTrue(result > 0);
}

[TestMethod()]
public void TestWhereAndFirst()
{
List<Simple> list = new List<Simple>(Range);
for (int i = Range - 1; i >= 0; --i)
{
list.Add(new Simple { Id = i, Value = 10 });
}

int result = 0;
for (int i = 0; i < Range; ++i)
{
result += list.Where(f => f.Id == i).First().Value;
}

Assert.IsTrue(result > 0);
}

最佳答案

我得到了相同的结果:where+first 比 first 更快。

正如 Jon 指出的那样,Linq 使用惰性求值,因此这两种方法的性能应该(并且确实)大致相似。

在 Reflector 中,首先使用一个简单的 foreach 循环遍历集合,但是 Where 有各种专门用于不同集合类型(数组、列表等)的迭代器。大概这就是给 Where 带来小优势的原因。

关于c# - 为什么 LINQ .Where(predicate).First() 比 .First(predicate) 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8663897/

24 4 0