[英]Understanding deferred execution performance
Suppose we have a list of students:假设我们有一个学生列表:
var students = new List<Student>(//fill with 5000 students);
We then find the youngest male student from this list:然后我们从这个列表中找到最年轻的男学生:
Method 1:方法一:
var youngestMaleStudent = students.Where(s => s.Gender == "male").OrderBy(s => s.Age).First();
Console.WriteLine(youngestMaleStudent.Name);
Method 2:方法二:
var maleStudents = students.Where(s => s.Gender == "male").ToList()
var youngestMaleStudent = maleStudents.OrderBy(s => s.Age).First();
Console.WriteLine(youngestMaleStudent.Name);
I would think Method 1 should be more efficient as Method 2 creates a new list and moves everything into it, but presumably, this isn't a huge deal as copying memory is relatively fast?我认为方法 1 应该更有效,因为方法 2 创建了一个新列表并将所有内容移入其中,但大概这不是什么大问题,因为复制 memory 相对较快? (though 5000 objects may start to weight things down)
(尽管 5000 个物体可能会开始减轻重量)
But then I think, do they run differently at all performance-wise?但后来我想,它们在性能方面的运行方式是否有所不同? How does LINQ process each step in Method 1, does it not need to copy everything into a list of some form in order to then start sorting (ordering) the data?
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 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.
This is obtained using fluent interface pattern .这是使用流畅的界面模式获得的。
What are the benefits of a Deferred Execution in LINQ? LINQ 中的延迟执行有什么好处?
Deferred Execution of LINQ Query (tutorialsteacher.com) 延迟执行 LINQ 查询 (tutorialsteacher.com)
Deferred Vs Immediate Query Execution in LINQ (c-sharpcorner.com) LINQ (c-sharpcorner.com) 中的延迟与立即查询执行
Therefore method 1 is faster because in method 2 ToList()
executes the query and First()
executes a new query.因此方法 1更快,因为在方法 2中
ToList()
执行查询,而First()
执行新查询。 Thus this last can be about 2x time at worst without considering underlying caches and optimizations.因此,在不考虑底层缓存和优化的情况下,这最后可能是最坏的大约 2 倍时间。 Because it uses an executed query (
ToList()
) to do an orderby on it that is a second executed query ( First()
).因为它使用执行的查询(
ToList()
)对其进行排序,这是第二个执行的查询( First()
)。
In other words, in method 1 , the query is executed only by the First()
method call and all previous calls are deferred to prepare the final query for this process like adding parameters in a string (in the case of SQL and it's about the same thing for any other target).换句话说,在方法 1中,查询仅由
First()
方法调用执行,并且所有先前的调用都被推迟以准备此过程的最终查询,例如在字符串中添加参数(在 SQL 的情况下,它是关于任何其他目标都一样)。 But in method 2 , the ToList()
creates a List<>
instance from an executed query that consumes time and memory, and next the First()
call do another query on this list, that consumes time and memory again...但是在方法 2中,
ToList()
从执行的查询创建一个List<>
实例,该查询消耗时间和 memory,然后First()
调用在此列表上执行另一个查询,这又消耗时间和 memory...
So it is important to check in the documentation of every Linq method if it is deferred or not.因此,重要的是检查每个 Linq 方法的文档是否延迟。
Linq can be both a performance and spaghetti code killer as well as a black hole. Linq 既可以是性能和意大利面条式代码杀手,也可以是黑洞。
In method 2 .ToList()
convert an IQuryable
to IEnumerable
and based on that, all data from database fetched and then students.Where(s => s.Gender == "male")
condition apply on it in memory.在方法 2
.ToList()
中,将IQuryable
转换为IEnumerable
,并在此基础上从数据库中获取所有数据,然后在 memory 中应用students.Where(s => s.Gender == "male")
条件。
In method 1 youngestMaleStudent
is IQuryable
then the query students.Where(s => s.Gender == "male").OrderBy(s => s.Age).First();
在方法 1 中,
youngestMaleStudent
是IQuryable
然后查询students.Where(s => s.Gender == "male").OrderBy(s => s.Age).First();
processed on database side.在数据库端处理。
The result is method 1 performed better specially when your data is huge.结果是方法 1 特别在您的数据很大时执行得更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.