C#收益回报表现 [英] C# yield return performance

查看:199
本文介绍了C#收益回报表现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

多少空间被保留使用收益回报语法的方法背后的深层集合时,我进行了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 =美孚(); 



尚未执行。没有什么会在控制台上进行打印。但是,如果我们遍历,就像这样:

 的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆