当Linq比Foreach快时,是否真的是这种情况? [英] Is this really a case when Linq is faster than a Foreach

查看:66
本文介绍了当Linq比Foreach快时,是否真的是这种情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您搜索的Linq速度更快,则Foreach答案永远不是foreach.我还发现了另一个stackoverflow问题,其中问题问询者未进行热身" /a>,所以我在代码中加入了预热".

If you search is Linq faster the Foreach the answer always is no a foreach is. I also found another stackoverflow question where the question asker had not done a "warmup" so I've included a "warmup" in my code.

由于某些原因,我的代码示例未按预期运行.我在想我做的是使no linq路径循环两次-第一次,一次总计.当linq示例进行求和时,其末尾仅循环一次.你怎么认为?我的测试有缺陷吗?还是这是linq实际为我们带来良好性能提升的情况?

My code example for some reason did not act as I expected. I'm thinking what I've done is make the no linq path loop twice--once the first time and once at the sum. Where as the linq example loops only once at the end when it does a sum. What do you think? Is my test flawed or is this a scenario where linq actually buys us a good performance increase?

    public class NumberObject { public Int32 Number { get; set; } }

    public IEnumerable<NumberObject> GetNumbersWithoutLambda()
    {
        IEnumerable<Int32> numberRange = Enumerable.Range(0,10);
        List<NumberObject> numberList = new List<NumberObject>();
        foreach (Int32 item in numberRange)
        {
            numberList.Add(new NumberObject() { Number = item });
        }
        return numberList;
    }

    public IEnumerable<NumberObject> GetNumbersWithLambda()
    {
        IEnumerable<Int32> numberRange = Enumerable.Range(0, 10);
        IEnumerable<NumberObject> numbers = numberRange.
            Select(number => new NumberObject() { Number = number });
        return numbers;
    }

    private void runGetNumbers(Func<IEnumerable<NumberObject>> getNumbersFunction, Int32 numberOfTimesToRun)
    {
        for (int i = 0; i < numberOfTimesToRun; i++)
        {
            IEnumerable<NumberObject> numbers = getNumbersFunction();
            //numbers.Count();
            numbers.Sum(item => item.Number);
            //numbers.Average(item => item.Number);
        }
    }

    [TestMethod]
    public void record_speed_of_GetNumbers()
    {
        Int32 numberOfTimes = 10000000;

        Console.WriteLine("Doing warmup... " +
            TimeMethod(() => runGetNumbers(GetNumbersWithLambda, numberOfTimes)));

        Console.WriteLine("GetNumbersWithoutLambda: " +
            TimeMethod(() => runGetNumbers(GetNumbersWithoutLambda, numberOfTimes)) + " milliseconds");

        Console.WriteLine("GetNumbersWithLambda: " +
            TimeMethod(() => runGetNumbers(GetNumbersWithLambda, numberOfTimes)) + " milliseconds");
    }

    static long TimeMethod(Action methodToTime)
    {
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();
        methodToTime();
        stopwatch.Stop();
        return stopwatch.ElapsedMilliseconds;
    }

下面是测试的输出:

正在热身... 7560

GetNumbersWithoutLambda: 14779毫秒

GetNumbersWithLambda: 7626毫秒

有趣的是,在这种情况下,热身"运行实际上似乎并不适用.

The interesting this is that the "warmup" run actually does not seem to apply in this case.

推荐答案

当使用延迟执行时,LINQ通常会更快.就像这里一样.

LINQ will usually be faster when it can take advantage of deferred execution; as it does here.

您怀疑; foreach完全枚举代码中的集合. Select只是建立一个查询来进行枚举.

As you suspected; foreach fully enumerates the collection in your code. Select just builds a query to do that enumeration.

然后,当您调用Sum时,它将枚举先前生成的集合.对于foreach,我们总共有2个枚举,对于Select,我们只有一个枚举,因此它更快(快2倍!)

Then when you call Sum, it enumerates the previously generated collection. We have a total of 2 enumerations for foreach and just one for Select, so it is faster (by a factor of 2!)

还有其他例子; TakeFirst将尽早停止执行(foreach 可以尽早停止,但是大多数人不会这样编码).

There are other examples; Take, and First will stop execution early (a foreach can stop early, but most people don't code it that way).

基本上,当您实际上需要枚举整个集合时,或者要枚举(使用)LINQ查询时,请使用foreach.在运行查询和操作时,可以使用LINQ,在这些查询和操作中延迟执行将为您带来性能优势.当该查询返回集合时,请使用foreach遍历 it .

Basically, use foreach when you actually need to enumerate the whole collection for what you are doing, or when you want to enumerate (consume) a LINQ query. Use LINQ when you are running queries and operations where deferred execution will get you a performance benefit. When that query returns a collection, use foreach to iterate over it.

这篇关于当Linq比Foreach快时,是否真的是这种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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