簡體   English   中英

哪種LINQ表達式更快

[英]Which LINQ expression is faster

大家好

在下面的代碼中

public class Person
{
    public string Name { get; set; }
    public uint Age { get; set; }

    public Person(string name, uint age)
    {
        Name = name;
        Age = age;
    }
}

void Main()
{
    var data = new List<Person>{ new Person("Bill Gates", 55), 
                                new Person("Steve Ballmer", 54), 
                                new Person("Steve Jobs", 55), 
                                new Person("Scott Gu", 35)};

    // 1st approach
    data.Where (x => x.Age > 40).ToList().ForEach(x => x.Age++);

    // 2nd approach
    data.ForEach(x => 
                    {
                        if (x.Age > 40)
                            x.Age++;
                    });

    data.ForEach(x => Console.WriteLine(x));    
}

在我的理解中,第二種方法應該更快,因為它會遍歷每個項目一次並且第一種方法運行兩次:

  1. Where子句
  2. 來自where子句的項目子集上的ForEach。

但是在內部,編譯器無論如何都會將第一種方法轉換為第二種方法,並且它們將具有相同的性能。

有什么建議或想法嗎?

我可以像建議的那樣進行概要分析,但是我想了解如果代碼行的內容與編譯器相同,或者編譯器將按字面意義對待,則在編譯器級別上會發生什么。

在此先感謝您的幫助。

我只運行了代碼,第二個運行得更快:

static void T3()
        {
            var data = new List<Person>{ new Person("Bill Gates", 55), 
                                new Person("Steve Ballmer", 54), 
                                new Person("Steve Jobs", 55), 
                                new Person("Scott Gu", 35)};

            System.Diagnostics.Stopwatch s1 = new System.Diagnostics.Stopwatch();

            s1.Start();
            // 1st approach
            data.Where(x => x.Age > 40).ToList().ForEach(x => x.Age++);
            s1.Stop();

            System.Diagnostics.Stopwatch s2 = new System.Diagnostics.Stopwatch();

            s2.Start();
            // 2nd approach
            data.ForEach(x =>
            {
                if (x.Age > 40)
                    x.Age++;
            });
            s2.Stop();

            Console.Write("s1: " + s1.ElapsedTicks + " S2:" + s2.ElapsedTicks);
            data.ForEach(x => Console.WriteLine(x));
        }

這是可以預期的,因為第二個不需要轉換為列表,然后運行foreach方法。

結果: s1:1192 S2:255

您反對.Where()而不加以衡量。 兩種方法之間的真正區別是.ToList()

第三種方法:

foreach(Person x in data.Where(x => x.Age > 40))
{
  x.Age++; 
}

將代碼粘貼到LinqPad(www.linqpad.net)中並對其計時。 或者,您可以檢查生成的IL代碼,以查看編譯器如何處理它。

我相信第一個會因為ToList()而變慢。 創建新的數據結構必須相對較慢。

如果您對編譯器如何處理這兩個表達式感興趣,為什么不對它們進行編譯,則使用ildasm工具(與Visual Studio捆綁在一起)查看生成的代碼?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM