有两个方面:速度和内存。
当您使用类似的方法时,速度方面会变得更加明显.Take()
仅消耗原始结果集的一部分。
// Consumes ten elements, yields 5 results.
Enumerable.Range(1, 1000000).Where(i => i % 2 == 0)
.Take(5)
.ToList();
// Consumes one million elements, yields 5 results.
Enumerable.Range(1, 1000000).Where(i => i % 2 == 0)
.OrderByDescending(i => i)
.Take(5)
.ToList();
因为第一个示例在调用之前仅使用流运算符Take
,之前您只会得到 1 到 10 的值Take
停止评估。此外,一次仅将一个值加载到内存中,因此内存占用非常小。
在第二个例子中,OrderByDescending
不是流式传输,因此当 Take 拉取第一个项目时,整个结果都会通过Where
过滤器必须放置在内存中进行排序。这可能需要很长时间并产生大量内存占用。
即使您没有使用Take
,内存问题可能很重要。例如:
// Puts half a million elements in memory, sorts, then outputs them.
var numbers = Enumerable.Range(1, 1000000).Where(i => i % 2 == 0)
.OrderByDescending(i => i);
foreach(var number in numbers) Console.WriteLine(number);
// Puts one element in memory at a time.
var numbers = Enumerable.Range(1, 1000000).Where(i => i % 2 == 0);
foreach(var number in numbers) Console.WriteLine(number);