我正在做一些性能测试,发现LINQ表达式
result = list.First(f => f.Id == i).Property
比
result = list.Where(f => f.Id == i).First().Property
这似乎有违直觉.我本以为第一个表达式会更快,因为它可以在满足谓词后立即停止迭代列表,而我会认为.Where()
表达式可能会在对结果子集调用.First()
之前迭代整个列表.即使后者确实短路了,它也不应该比直接使用第一个快,但它确实是快的.
下面是两个非常简单的单元测试来说明这一点.当在TestWherendFirst上进行优化编译时,比仅在TestFirstOnly上编译快约30%.Net和Silverlight 4.我try 过让谓词返回更多结果,但性能差异是相同的.
Can any one explain why .First(fn)
比 .Where(fn).First()
? I see a similar counter intuitive result with .Count(fn)
compared to .Where(fn).Count()
.
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);
}