gpt4 book ai didi

c# - 如果多次使用,是否应该评估从 OrderBy 返回的 IEnumerable?

转载 作者:行者123 更新时间:2023-11-30 19:09:38 27 4
gpt4 key购买 nike

我正在查看一些调用扩展方法的代码 OrderBy .生成的 IEnumerable 可能会被多次使用。我听说对于 LINQ,如果表达式可能被多次使用,最好对它们求值,因为如果不这样做,LINQ 查询将被执行多次。这里也是这样吗? (最初,看代码,我没有意识到这是 LINQ,但我从 MSDN 文档中看到 OrderBy 在 LINQ 命名空间中。)

具体来说,代码看起来像这样,除了被枚举的项比 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));
}
}

无论我是否使用 .ToList(),这段代码都有相同的输出。

1
2, 6
3, 9, 12

这段代码可能会一遍又一遍地排序,这似乎有点令人惊讶。但如果是,我应该有 .ToList(),输出是相同的,那么一般来说,我应该如何知道 .ToList()是必须的?是不是单纯的看到了魔语

deferred execution

在文档中?


为了解决@Matt Burland 的建议,即我应该自己测试性能,我将程序更改为以下内容(使用 double 以避免溢出问题)。

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);
}
}
}

结果:

  • 没有 ToList,115 毫秒
  • 使用 ToList,10 毫秒

(sum 在这两种情况下是相同的)

最佳答案

当您使用 Linq 表达式时,表达式的结果不是在表达式定义时计算的,而是在您对其进行迭代时计算的。

如果您多次迭代,将计算结果(如果更改了 linq 表达式中使用的基本列表,结果可能会有所不同)。

如果您使用 ToList() 并保留该方法的结果,结果将只计算一次,并且当您对 ToList() 方法的结果进行多次迭代时,您肯定会得到相同的结果输出。

关于c# - 如果多次使用,是否应该评估从 OrderBy 返回的 IEnumerable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24455977/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com