Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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# 多个Where语句的最佳使用_C#_Performance_Linq_Where - Fatal编程技术网

C# 多个Where语句的最佳使用

C# 多个Where语句的最佳使用,c#,performance,linq,where,C#,Performance,Linq,Where,以下请求是否自动“优化” 这相当于 var result = initial .Where(e => Predicate1(e) && Predicate2(e) && Predicate3(e)); 这两个语句中哪一个更优化?或者它们是相同的?不,不是。这些,其中方法调用未合并为一个 c#代码: var输入=新列表(); 变量输出=输入。其中(x=>x.StartsWith(“测试”))。其中(x=>x.Length>10

以下请求是否自动“优化”

这相当于

var result = initial
                .Where(e => Predicate1(e) && Predicate2(e) && Predicate3(e));

这两个语句中哪一个更优化?或者它们是相同的?

不,不是。这些
,其中
方法调用未合并为一个

c#代码:

var输入=新列表();
变量输出=输入。其中(x=>x.StartsWith(“测试”))。其中(x=>x.Length>10)。其中(x=>!x.EndsWith(“测试”);
生成的IL:

IL_0000: newobj instance void class [mscorlib]System.Collections.Generic.List`1<string>::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: ldsfld class [mscorlib]System.Func`2<string, bool> ConsoleApplication2.Program::'CS$<>9__CachedAnonymousMethodDelegate3'
IL_000c: brtrue.s IL_001f

IL_000e: ldnull
IL_000f: ldftn bool ConsoleApplication2.Program::'<Main>b__0'(string)
IL_0015: newobj instance void class [mscorlib]System.Func`2<string, bool>::.ctor(object, native int)
IL_001a: stsfld class [mscorlib]System.Func`2<string, bool> ConsoleApplication2.Program::'CS$<>9__CachedAnonymousMethodDelegate3'

IL_001f: ldsfld class [mscorlib]System.Func`2<string, bool> ConsoleApplication2.Program::'CS$<>9__CachedAnonymousMethodDelegate3'
IL_0024: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<string>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [mscorlib]System.Func`2<!!0, bool>)
IL_0029: ldsfld class [mscorlib]System.Func`2<string, bool> ConsoleApplication2.Program::'CS$<>9__CachedAnonymousMethodDelegate4'
IL_002e: brtrue.s IL_0041

IL_0030: ldnull
IL_0031: ldftn bool ConsoleApplication2.Program::'<Main>b__1'(string)
IL_0037: newobj instance void class [mscorlib]System.Func`2<string, bool>::.ctor(object, native int)
IL_003c: stsfld class [mscorlib]System.Func`2<string, bool> ConsoleApplication2.Program::'CS$<>9__CachedAnonymousMethodDelegate4'

IL_0041: ldsfld class [mscorlib]System.Func`2<string, bool> ConsoleApplication2.Program::'CS$<>9__CachedAnonymousMethodDelegate4'
IL_0046: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<string>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [mscorlib]System.Func`2<!!0, bool>)
IL_004b: ldsfld class [mscorlib]System.Func`2<string, bool> ConsoleApplication2.Program::'CS$<>9__CachedAnonymousMethodDelegate5'
IL_0050: brtrue.s IL_0063

IL_0052: ldnull
IL_0053: ldftn bool ConsoleApplication2.Program::'<Main>b__2'(string)
IL_0059: newobj instance void class [mscorlib]System.Func`2<string, bool>::.ctor(object, native int)
IL_005e: stsfld class [mscorlib]System.Func`2<string, bool> ConsoleApplication2.Program::'CS$<>9__CachedAnonymousMethodDelegate5'

IL_0063: ldsfld class [mscorlib]System.Func`2<string, bool> ConsoleApplication2.Program::'CS$<>9__CachedAnonymousMethodDelegate5'
IL_0068: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<string>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [mscorlib]System.Func`2<!!0, bool>)
IL_006d: pop
IL_006e: ret
IL_0000:newobj实例无效类[mscorlib]System.Collections.Generic.List`1::.ctor()
IL_0005:stloc.0
IL_0006:ldloc.0
IL_0007:ldsfld类[mscorlib]System.Func`2控制台应用程序2.Program:'CS$9_ucachedanonymousmethoddelegate3'
IL_000c:brtrue.s IL_001f
IL_000e:ldnull
IL_000f:ldftn布尔控制台应用程序2.程序::'b__0'(字符串)
IL_0015:newobj实例无效类[mscorlib]System.Func`2::.ctor(对象,本机int)
IL_001a:stsfld类[mscorlib]System.Func`2控制台应用程序2.Program:'CS$9_ucachedanonymousmethoddelegate3'
IL_001f:ldsfld类[mscorlib]系统。函数'2控制台应用程序2。程序:'CS$9_ucachedanonymousmethoddelegate3'
IL_0024:调用类[mscorlib]System.Collections.Generic.IEnumerable`1[System.Core]System.Linq.Enumerable::Where(类[mscorlib]System.Collections.Generic.IEnumerable`1,类[mscorlib]System.Func`2)
IL_0029:ldsfld类[mscorlib]System.Func`2控制台应用程序2.Program:'CS$9_ucachedanonymousmethoddelegate4'
IL_002e:brtrue.s IL_0041
IL_0030:ldnull
IL_0031:ldftn布尔控制台应用程序2.程序::'b__1'(字符串)
IL_0037:newobj实例无效类[mscorlib]System.Func`2::.ctor(对象,本机int)
IL_003c:stsfld类[mscorlib]System.Func`2控制台应用程序2.Program:'CS$9_ucachedanonymousmethoddelegate4'
IL_0041:ldsfld类[mscorlib]System.Func`2控制台应用程序2.Program:'CS$9_ucachedanonymousmethoddelegate4'
IL_0046:调用类[mscorlib]System.Collections.Generic.IEnumerable`1[System.Core]System.Linq.Enumerable::Where(类[mscorlib]System.Collections.Generic.IEnumerable`1,类[mscorlib]System.Func`2)
IL_004b:ldsfld类[mscorlib]System.Func`2控制台应用程序2.程序::'CS$9_CachedAnonymousMethodDelegate5'
IL_0050:brtrue.s IL_0063
IL_0052:ldnull
IL_0053:ldftn布尔控制台应用程序2.程序::'b__2'(字符串)
IL_0059:newobj实例无效类[mscorlib]System.Func`2::.ctor(对象,本机int)
IL_005e:stsfld类[mscorlib]System.Func`2控制台应用程序2.程序::'CS$9_CachedAnonymousMethodDelegate5'
IL_0063:ldsfld类[mscorlib]System.Func`2控制台应用程序2.Program:'CS$9_ucachedanonymousmethoddelegate5'
IL_0068:调用类[mscorlib]System.Collections.Generic.IEnumerable`1[System.Core]System.Linq.Enumerable::Where(类[mscorlib]System.Collections.Generic.IEnumerable`1,类[mscorlib]System.Func`2)
IL_006d:流行音乐
IL_006e:ret

如您所见,有3个
System.Linq.Enumerable::Where
调用。

虽然编译的代码没有组合谓词,但执行基本上是这样。Linq的Where方法在传递列表时返回WhereListIterator。WhereListIterator有自己的Where方法实现,该实现返回一个新的WhereListIterator,并结合谓词。看起来是这样的:

返回新的Enumerable.WhereListIterator(this.source,Enumerable.CombinePredicates(this.predicate,predicate)

其中this.source是列表,this.predicate是第一个where的谓词,谓词来自第二个where

CombinePredicates返回包含以下代码的委托:

if (predicate1(source)) return predicate2(source);
return false;
因此链式Where子句的结尾应该是:

if (predicate1(source)) {
    if (predicate2(source) {
        return predicate3(source) {
    } 
    return false;
 }
 return false;

对于一个小列表,使用&&将谓词组合到一个Where中可能更有效,但随着列表大小的增加,这两个选项的运行时可能会变得相似。您必须对其进行分析,以量化差异。我怀疑它不够大,不太重要。

尽管我认为它实际上是相同的,但短路评估。@Ginosaji是的,这是一样的,但编译器不会优化。你必须自己做。这很有趣。回答得很好!只检查了
可枚举性。Where
实现,你是对的!总是有时间学习新东西。WhereEnumera的这种行为相同吗迭代器?
if (predicate1(source)) return predicate2(source);
return false;
if (predicate1(source)) {
    if (predicate2(source) {
        return predicate3(source) {
    } 
    return false;
 }
 return false;