gpt4 book ai didi

.net - 其中 lambda 与第一个 lambda

转载 作者:行者123 更新时间:2023-12-04 05:54:04 26 4
gpt4 key购买 nike

假设我有一些字符串:

string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

有什么区别:
string startsWithO = strings.First(s => s[0] == 'o');

和:
string startsWithO = strings.Where(s => s[0] == 'o').First();

由于 Where() 被推迟,它不应该减慢执行速度,对吗?

最佳答案

使用 .Where(filter).First() 的性能损失而不是 .First(filter)通常会非常小。

然而,它们并不相同 - Where生成一个新的迭代器 First可以简单地取一个元素,而 First(filter)只要 filter 就可以通过使用一个循环和直接返回来微优化火柴。

因此,虽然两种方法具有相同的语义并且都执行 filter同样经常(仅在必要时),使用 Firstfilter参数不需要创建中间迭代器对象,并且可能也避免了对该迭代器的一些非常简单的方法调用。

换句话说,如果你执行这样的代码数百万次,您会看到轻微的性能差异 - 但没什么大不了的;我永远不会担心它。每当这种微小的性能差异实际上很重要时,您最好只编写等效的(非常简单的)foreach-with-if 语句并避免 LINQ 中固有的额外调用和对象分配 - 但请记住,这是一个微优化,您将很少需要。

编辑:展示效果的基准:

这需要 0.78 秒:

for(int i=0;i<10*1000*1000;i++)
Enumerable.Range(0,1000).First(n=> n > 2);
GC.Collect();

但这需要 1.41 秒:
for(int i=0;i<10*1000*1000;i++)
Enumerable.Range(0,1000).Where(n=> n > 2).First();
GC.Collect();

而普通循环要快得多(0.13 秒):
long bla = 0;
for(int i=0;i<10*1000*1000;i++)
for(int n=0;n<1000;n++)
if(n > 2) { bla+=n; break; }
GC.Collect();
Console.WriteLine(bla);//avoid optimizer cheating.

请注意,此基准测试仅显示出如此极端的差异,因为我有一个简单的过滤器和一个非常短的非匹配前缀。

根据一些快速实验,差异似乎主要归因于所采用的代码路径的细节。因此,对于数组和 List<> s 第一个变体实际上更快,可能在 .Where 中做特殊 shell 对于那些 First 的类型没有;对于自定义迭代器,正如预期的那样,第二个版本要快一点。

概括:
.Where(...).First()大致与 .First(...) 一样快- 不要费心选择一个或另一个作为优化。一般情况 .First(...)速度非常快,但在某些常见情况下它会更慢。如果你真的需要那个微优化,那么使用比两者都快的普通循环。

关于.net - 其中 lambda 与第一个 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14262003/

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