Too*_*one 2 .net c# linq sorting
我正在看一些调用扩展方法的代码OrderBy.结果IEnumerable可能会多次使用.我已经听说过使用LINQ,如果表达式可能被多次使用,那么最好对它们进行评估,因为如果不这样做,LINQ查询将被执行多次.这也是这种情况吗?(最初,查看代码,我没有意识到它是LINQ,但我从MSDN文档中看到OrderBy了LINQ命名空间.)
为了使其具体化,代码看起来像这样,除了枚举的项目比a更复杂,int并且可能比这个简单示例中的更多数量级.
IEnumerable<int> Multiply(IEnumerable<int> list, int howMany, int k)
{
return list.Take(howMany).Select(i => i * k);
}
void Main()
{
int[] unsorted = { 1, 7, 3, 9, 4 };
IEnumerable<int> sorted = unsorted.OrderBy(i=>i); // Add .ToList() ?
for(int k=1; k<=3; ++k) {
IEnumerable<int> multiplied = Multiply(sorted, k, k);
Console.WriteLine(String.Join(", ", multiplied));
}
}
Run Code Online (Sandbox Code Playgroud)
无论我是否使用,此代码都具有相同的输出.ToList().
1
2, 6
3, 9, 12
Run Code Online (Sandbox Code Playgroud)
看起来有点令人惊讶的是,这段代码可能会反复排序.但如果它是,而且我应该有.ToList(),那么输出是相同的,那么一般来说,我应该知道这.ToList()是必需的吗?它只是看到了神奇的话语
延期执行
在文档中?
为了解决@Matt Burland的建议,我应该为自己测试性能,我将程序改为以下(使用doubles来避免溢出问题).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
namespace OrderByPerformanceTest
{
class Program
{
static IEnumerable<double> Multiply(IEnumerable<double> list, int howMany, double k)
{
return list.Take(howMany).Select(i => i * k);
}
static void Main(string[] args)
{
int n = 1000;
IEnumerable<double> unsorted = Enumerable.Range(0, n).Select(i => (double)(n-i));
//Console.WriteLine(String.Join(", ", unsorted));
IEnumerable<double> sorted1 = unsorted.OrderBy(i => i); // Add .ToList() ?
//Console.WriteLine(String.Join(", ", sorted1));
var sw = new Stopwatch();
sw.Start();
double sum = 0;
for (int k = 1; k <= n; ++k)
{
IEnumerable<double> multiplied = Multiply(sorted1, k, k);
sum += multiplied.Sum();
//Console.WriteLine(String.Join(", ", multiplied));
}
sw.Stop();
Console.WriteLine("Time {0}ms, sum {1}", sw.ElapsedMilliseconds, sum);
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
ToList,115毫秒ToList,10ms(sum两种情况都相同)
使用Linq表达式时,表达式的结果不会在表达式的定义中计算,而是在迭代时计算.
如果多次迭代,将计算结果(如果更改linq表达式中的基本列表,则结果可能不同).
如果你使用ToList()并保留方法的结果,结果将立即计算,只有一次,当你在ToList()方法的结果上多次迭代时,你肯定会有相同的输出.
| 归档时间: |
|
| 查看次数: |
376 次 |
| 最近记录: |