Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Linq结果上迭代时出现奇怪的慢度_C#_Linq - Fatal编程技术网

C# 在Linq结果上迭代时出现奇怪的慢度

C# 在Linq结果上迭代时出现奇怪的慢度,c#,linq,C#,Linq,在研究最近的一个问题时,我注意到算法似乎相当慢。深入挖掘,我注意到花费了很长时间的不是linq代码,而是结果的输出。(顺便说一句,马克·格拉斯踢出了我见过的最光滑的林克,这是我的荣幸。) 代码: 输出: Alg Start 20.257 Alg End 20.270 109989 x 9 = 989901 219978 x 4 = 879912 1099989 x 9 = 9899901 Disp End 31.322 .13秒计算,超过11秒显示?!?原因是什么?linq查询看起来执

在研究最近的一个问题时,我注意到算法似乎相当慢。深入挖掘,我注意到花费了很长时间的不是linq代码,而是结果的输出。(顺便说一句,马克·格拉斯踢出了我见过的最光滑的林克,这是我的荣幸。)

代码:


输出:

Alg Start 20.257
Alg End   20.270
109989 x 9 = 989901
219978 x 4 = 879912
1099989 x 9 = 9899901
Disp End  31.322

.13秒计算,超过11秒显示?!?原因是什么?

linq查询看起来执行得很快的原因是,在定义点上实际上没有计算任何内容,因为linq使用延迟执行,即,在开始枚举结果之前,不会执行任何“实际”工作。

原因是,在枚举结果之前,查询不会实际运行。在LINQto对象中,它只设置一组委托,当您迭代枚举器时,这些委托将被调用。如果要向查询中添加ToList()来具体化它,您将看到所花费的时间将转移到设置和远离显示。

对于许多linq提供程序,“alg start”到“alt end”只是解析而已-实际表达式在您实际开始枚举结果之前不会计算。因此,“qry”变量的实际创建速度很快(只需设置一个实际执行查询逻辑的可枚举项),但通过该变量进行枚举的速度较慢。

LINQ代码只在查询表达式之外创建一个查询对象,这不会占用很多时间。只有在foreach中才实际执行查询


顺便说一句,您不应该使用DateTime.Now进行性能计时,但是使用Stopwatch类,因为它更精确。

在您迭代查询之前,查询实际上不会计算。在此之前,它就像一个SQL语句,等待执行。

这个问题是在进行暴力强迫;在这种情况下,LINQ实际上非常方便——我在这里讨论了这一点:

仅对前面的一些答案进行扩展:

LINQ通常是围绕延迟执行而设计的,这意味着在开始迭代结果之前不会发生任何事情。这通常通过迭代器块完成;考虑这些之间的差异:

static IEnumerable<T> Where(this IEnumerable<T> data, Func<T,bool> predicate) {
    foreach(T item in data) {
        if(predicate(item)) yield return item;
    }
}

如果没有延迟执行,这将永远不会完成。

请记住:查询表达式的结果是查询,而不是查询的结果。在向查询请求结果之前,您不会得到查询结果;我稍后发布的版本应该更快。。。但是延迟执行是这里的关键。
static IEnumerable<T> Where(this IEnumerable<T> data, Func<T,bool> predicate) {
    foreach(T item in data) {
        if(predicate(item)) yield return item;
    }
}
static IEnumerable<T> Where(this IEnumerable<T> data, Func<T,bool> predicate) {
    var list = new List<T>();
    foreach(T item in data) {
        if(predicate(item)) list.Add(item);
    }
    return list;
}
    foreach (long i in Fibonacci().Take(10)) {
        Console.WriteLine(i);
    }