是“回报收益率”比&QUOT慢,老同学和QUOT;返回? [英] Is 'yield return' slower than "old school" return?

查看:137
本文介绍了是“回报收益率”比&QUOT慢,老同学和QUOT;返回?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做关于收益率的回报性能比较一些测试,我发现它比正常的回归慢。



我测试值的变量(INT,双,等)和一些参考类型(字符串,等等。)...和产量均收益在两种情况下慢。 ?为什么要使用它,然后



看看我的例子:

 公开类YieldReturnTeste 
{
私有静态的IEnumerable<串GT; YieldReturnTest(INT LIMITE)
{
的for(int i = 0; I< LIMITE;我++)
{
收益率的回报i.ToString();
}
}

私有静态的IEnumerable<串GT; NormalReturnTest(INT LIMITE)
{
名单,LT;字符串> listaInteiros =新的List<串GT;();

的for(int i = 0; I< LIMITE;我++)
{
listaInteiros.Add(i.ToString());
}
返回listaInteiros;
}

公共静态无效executaTeste()
{
秒表=新的秒表();

stopWatch.Start();

名单,LT;字符串> minhaListaYield = YieldReturnTest(2000000).ToList();

stopWatch.Stop();

时间跨度TS = stopWatch.Elapsed;


串elapsedTime =的String.Format({0点○○} {} 1点00分:{2点} {} 3点00分,

ts.Hours,ts.Minutes,ts.Seconds,

ts.Milliseconds / 10);

Console.WriteLine(产量返程:{0},elapsedTime);

// ****

秒表=新秒表();

stopWatch.Start();

名单,LT;字符串> minhaListaNormal = NormalReturnTest(2000000).ToList();

stopWatch.Stop();

TS = stopWatch.Elapsed;


elapsedTime =的String.Format({} 0:00:{} 1:00:{2:00} {} 3:00,

ts.Hours,ts.Minutes,ts.Seconds,

ts.Milliseconds / 10);

Console.WriteLine(正常返回:{0},elapsedTime);
}
}


解决方案

考虑 File.ReadAllLines 之间的差异, File.ReadLines



ReadAllLines 加载所有线路到内存中,并返回一个的String [] 。一切都很好,如果文件很小。如果文件大于将适合在内存中,你会耗尽内存。



readlines方法,在另一方面,使用收益回报率在一次返回一行。有了它,你可以读取任何大小的文件。它不整个文件加载到内存中。



假设你想找到包含单词富,然后退出第一线。使用 ReadAllLines ,你必须读取整个文件到内存中,即使在第一行出现富。随着 readlines方法,只读取一行。哪一个会更快?



这不是唯一的原因。考虑一个程序,读取文件和处理每一行。使用 File.ReadAllLines ,你结束了:

 的String []线= File.ReadAllLines(文件名); 
的for(int i = 0; I< lines.Length ++ I)
{
//工艺路线
}

它需要该程序执行的时间是等于花费读取文件,加上时间来处理线的时间。试想一下,在处理需要很长时间要使用多个线程来加快速度。所以,你做这样的事情:

  =行File.ReadAllLines(文件名); 
Parallel.Foreach(...);



但读书是单线程的。您的多个线程无法启动,直到主线程加载整个文件。



通过 readlines方法,不过,你可以这样做:

  Parallel.Foreach(File.ReadLines(文件名),行= GT; {ProcessLine从(线) ;}); 



即启动立即多个线程,这是在同一时间,其他行被读取处理。所以,阅读时间是重叠的处理时间,这意味着你的程序将执行得更快。



我显示了使用文件,因为它更容易证明,这样的概念我的例子,但同样在内存中集合成立。使用收益回报率将使用较少的内存,并具有潜在的更快,特别是呼吁只需要看看集合( Enumerable.Any <部分方法时, / code>, Enumerable.First ,等等)。


I'm doing some tests about yield return perfomance, and I found that it is slower than normal return.

I tested value variables (int, double, etc.) and some references types (string, etc.)... And yield return were slower in both cases. Why use it then?

Check out my example:

public class YieldReturnTeste
{
    private static IEnumerable<string> YieldReturnTest(int limite)
    {
        for (int i = 0; i < limite; i++)
        {
            yield return i.ToString();
        }
    }

    private static IEnumerable<string> NormalReturnTest(int limite)
    {
        List<string> listaInteiros = new List<string>();

        for (int i = 0; i < limite; i++)
        {
            listaInteiros.Add(i.ToString());
        }
        return listaInteiros;
    }

    public static void executaTeste()
    {
        Stopwatch stopWatch = new Stopwatch();

        stopWatch.Start();

        List<string> minhaListaYield = YieldReturnTest(2000000).ToList();

        stopWatch.Stop();

        TimeSpan ts = stopWatch.Elapsed;


        string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",

        ts.Hours, ts.Minutes, ts.Seconds,

        ts.Milliseconds / 10);

        Console.WriteLine("Yield return: {0}", elapsedTime);

        //****

        stopWatch = new Stopwatch();

        stopWatch.Start();

        List<string> minhaListaNormal = NormalReturnTest(2000000).ToList();

        stopWatch.Stop();

        ts = stopWatch.Elapsed;


        elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",

        ts.Hours, ts.Minutes, ts.Seconds,

        ts.Milliseconds / 10);

        Console.WriteLine("Normal return: {0}", elapsedTime);
    }
}

解决方案

Consider the difference between File.ReadAllLines and File.ReadLines.

ReadAllLines loads all of the lines into memory and returns a string[]. All well and good if the file is small. If the file is larger than will fit in memory, you'll run out of memory.

ReadLines, on the other hand, uses yield return to return one line at a time. With it, you can read any size file. It doesn't load the whole file into memory.

Say you wanted to find the first line that contains the word "foo", and then exit. Using ReadAllLines, you'd have to read the entire file into memory, even if "foo" occurs on the first line. With ReadLines, you only read one line. Which one would be faster?

That's not the only reason. Consider a program that reads a file and processes each line. Using File.ReadAllLines, you end up with:

string[] lines = File.ReadAllLines(filename);
for (int i = 0; i < lines.Length; ++i)
{
    // process line
}

The time it takes that program to execute is equal to the time it takes to read the file, plus time to process the lines. Imagine that the processing takes so long that you want to speed it up with multiple threads. So you do something like:

lines = File.ReadAllLines(filename);
Parallel.Foreach(...);

But the reading is single-threaded. Your multiple threads can't start until the main thread has loaded the entire file.

With ReadLines, though, you can do something like:

Parallel.Foreach(File.ReadLines(filename), line => { ProcessLine(line); });

That starts up multiple threads immediately, which are processing at the same time that other lines are being read. So the reading time is overlapped with the processing time, meaning that your program will execute faster.

I show my examples using files because it's easier to demonstrate the concepts that way, but the same holds true for in-memory collections. Using yield return will use less memory and is potentially faster, especially when calling methods that only need to look at part of the collection (Enumerable.Any, Enumerable.First, etc.).

这篇关于是“回报收益率”比&QUOT慢,老同学和QUOT;返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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