[英]Understanding deferred execution performance
假设我们有一个学生列表:
var students = new List<Student>(//fill with 5000 students);
然后我们从这个列表中找到最年轻的男学生:
方法一:
var youngestMaleStudent = students.Where(s => s.Gender == "male").OrderBy(s => s.Age).First();
Console.WriteLine(youngestMaleStudent.Name);
方法二:
var maleStudents = students.Where(s => s.Gender == "male").ToList()
var youngestMaleStudent = maleStudents.OrderBy(s => s.Age).First();
Console.WriteLine(youngestMaleStudent.Name);
我认为方法 1 应该更有效,因为方法 2 创建了一个新列表并将所有内容移入其中,但大概这不是什么大问题,因为复制 memory 相对较快? (尽管 5000 个物体可能会开始减轻重量)
但后来我想,它们在性能方面的运行方式是否有所不同? LINQ如何处理方法1中的每个步骤,是否不需要将所有内容复制到某种形式的列表中才能开始对数据进行排序(排序)?
Linq deferred execution allows to enqueue, or to chain, differents parts of a query like select , where and order , as for SQL , which is executed when it is used, with a foreach
or a ToList()
for example.
这是使用流畅的界面模式获得的。
延迟执行 LINQ 查询 (tutorialsteacher.com)
LINQ (c-sharpcorner.com) 中的延迟与立即查询执行
因此方法 1更快,因为在方法 2中ToList()
执行查询,而First()
执行新查询。 因此,在不考虑底层缓存和优化的情况下,这最后可能是最坏的大约 2 倍时间。 因为它使用执行的查询( ToList()
)对其进行排序,这是第二个执行的查询( First()
)。
换句话说,在方法 1中,查询仅由First()
方法调用执行,并且所有先前的调用都被推迟以准备此过程的最终查询,例如在字符串中添加参数(在 SQL 的情况下,它是关于任何其他目标都一样)。 但是在方法 2中, ToList()
从执行的查询创建一个List<>
实例,该查询消耗时间和 memory,然后First()
调用在此列表上执行另一个查询,这又消耗时间和 memory...
因此,重要的是检查每个 Linq 方法的文档是否延迟。
Linq 既可以是性能和意大利面条式代码杀手,也可以是黑洞。
在方法 2 .ToList()
中,将IQuryable
转换为IEnumerable
,并在此基础上从数据库中获取所有数据,然后在 memory 中应用students.Where(s => s.Gender == "male")
条件。
在方法 1 中, youngestMaleStudent
是IQuryable
然后查询students.Where(s => s.Gender == "male").OrderBy(s => s.Age).First();
在数据库端处理。
结果是方法 1 特别在您的数据很大时执行得更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.