C#收益回报表现 [英] C# yield return performance
问题描述
多少空间被保留使用收益回报语法的方法背后的深层集合时,我进行了ToList()就可以了? ?有一个机会,它会重新分配,因此如果比较的地方,我创建具有预定容量列表中的标准方法降低性能
两个场景:
公开的IEnumerable< T> GetList1()
{
的foreach(在收集VAR项)
收益率的回报item.Property;
}
公开的IEnumerable< T> GetList2()
{
名单< T> outputList =新的List< T>(collection.Count());
的foreach(在收集VAR项)
outputList.Add(item.Property);
返回outputList;
}
回报收益率
不创建具有调整大小,像什么列表
不数组;相反,它创建了一个的IEnumerable
用状态机
例如,让我们这个方法:
公共静态的IEnumerable< INT>美孚()
{
Console.WriteLine(回归1);
收益率的回报1;
Console.WriteLine(返2);
收益率回归2;
Console.WriteLine(回归3);
收益率的回报3;
}
现在让我们叫它并分配枚举变量:
VAR elems =美孚();
无在富代码code>尚未执行。没有什么会在控制台上进行打印。但是,如果我们遍历,就像这样:
的foreach(在elems VAR ELEM)
{
Console.WriteLine(得到+ ELEM);
}
在的第一次迭代的foreach
循环中,富
方法,直到第一个收益率回报被执行
。然后,在第二次迭代,该方法从上次停止的地方(右后收益回报1
)将恢复,并执行,直到下一个收益回报率
。 。同所有后续元素结果
在循环结束时,控制台将是这样的:
返回1
获得1
返回2
获得2
返回3
获得3
这意味着你可以写这样的方法:
公共静态的IEnumerable< INT> ; GetAnswers()
{
,而(真)
{
收益回报42;
}
}
您可以致电 GetAnswers
方法,并且您每次请求一个元素时,它会给你42;该序列永远不会结束。你不能用列表
,因为列表必须有一个有限的大小。
这样做
How much space is reserved to the underlying collection behind a method using yield return syntax WHEN I PERFORM a ToList() on it? There's a chance it will reallocate and thus decrease performance if compared to the standard approach where i create a list with predefined capacity?
The two scenarios:
public IEnumerable<T> GetList1()
{
foreach( var item in collection )
yield return item.Property;
}
public IEnumerable<T> GetList2()
{
List<T> outputList = new List<T>( collection.Count() );
foreach( var item in collection )
outputList.Add( item.Property );
return outputList;
}
yield return
does not create an array that has to be resized, like what List
does; instead, it creates an IEnumerable
with a state machine.
For instance, let's take this method:
public static IEnumerable<int> Foo()
{
Console.WriteLine("Returning 1");
yield return 1;
Console.WriteLine("Returning 2");
yield return 2;
Console.WriteLine("Returning 3");
yield return 3;
}
Now let's call it and assign that enumerable to a variable:
var elems = Foo();
None of the code in Foo
has executed yet. Nothing will be printed on the console. But if we iterate over it, like this:
foreach(var elem in elems)
{
Console.WriteLine( "Got " + elem );
}
On the first iteration of the foreach
loop, the Foo
method will be executed until the first yield return
. Then, on the second iteration, the method will "resume" from where it left off (right after the yield return 1
), and execute until the next yield return
. Same for all subsequent elements.
At the end of the loop, the console will look like this:
Returning 1
Got 1
Returning 2
Got 2
Returning 3
Got 3
This means you can write methods like this:
public static IEnumerable<int> GetAnswers()
{
while( true )
{
yield return 42;
}
}
You can call the GetAnswers
method, and every time you request an element, it'll give you 42; the sequence never ends. You couldn't do this with a List
, because lists have to have a finite size.
这篇关于C#收益回报表现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!