簡體   English   中英

為什么LINQ在這個例子中更快

[英]Why is LINQ faster in this example

我寫了以下內容來測試使用foreach vs LINQ的性能:

private class Widget
{
    public string Name { get; set; }
}

static void Main(string[] args)
{
    List<Widget> widgets = new List<Widget>();
    int found = 0;

    for (int i = 0; i <= 500000 - 1; i++)
        widgets.Add(new Widget() { Name = Guid.NewGuid().ToString() });

    DateTime starttime = DateTime.Now;

    foreach (Widget w in widgets)
    {
        if (w.Name.StartsWith("4"))
            found += 1;
    }

    Console.WriteLine(found + " - " + DateTime.Now.Subtract(starttime).Milliseconds + " ms");

    starttime = DateTime.Now;
    found = widgets.Where(a => a.Name.StartsWith("4")).Count();

    Console.WriteLine(found + " - " + DateTime.Now.Subtract(starttime).Milliseconds + " ms");

    Console.ReadLine();
}

我得到類似以下輸出:

31160 - 116ms
31160 - 95 ms

在每次運行中,LINQ都比foreach高出約20%。 據我所知,LINQ擴展方法使用了標准的c#。

那么為什么LINQ在這種情況下會更快?

編輯:

所以我改變了我的代碼使用秒表而不是datetime仍然得到相同的結果。 如果我先運行LINQ查詢,那么我的結果顯示LINQ比foreach慢約20%。 這必須是某種JIT熱身問題。 我的問題是如何在我的測試用例中補償JIT熱身?

這是因為你沒有熱身。 如果你扭轉案件,你會得到相反的結果:

31272 - 110ms
31272 - 80 ms

開始添加預熱並使用秒表以獲得更好的計時。

用預熱運行測試:

        //WARM UP:
        widgets.Where(a => a.Name.StartsWith("4")).Count();

        foreach (Widget w in widgets)
        {
            if (w.Name.StartsWith("4"))
                found += 1;
        }

        //RUN Test
        Stopwatch stopwatch1 = new Stopwatch();
        stopwatch1.Start();

        found = widgets.Where(a => a.Name.StartsWith("4")).Count();
        stopwatch1.Stop();

        Console.WriteLine(found + " - " + stopwatch1.Elapsed);

        found = 0;
        Stopwatch stopwatch2 = new Stopwatch();
        stopwatch2.Start();

        foreach (Widget w in widgets)
        {
            if (w.Name.StartsWith("4"))
                found += 1;
        }
        stopwatch2.Stop();

        Console.WriteLine(found + " - " + stopwatch2.Elapsed);

結果:

31039 - 00:00:00.0783508
31039 - 00:00:00.0766299

我做了一段時間的分析,比較以下內容:

  • 具有/不具有正則表達式的對象的LINQ

  • 帶/不帶正則表達式的Lambda表達式

  • 帶/不帶正則表達式的傳統迭代

我發現LINQ,Lambda和Traditional迭代總是相同,但真正的時序差異在於Regex表達式。 只有添加正則表達式才能使評估更慢(慢一點)。 (詳情請見: http//www.midniteblog.com/?p = 72

您在上面看到的可能是因為您在同一個代碼塊中進行了兩個測試。 嘗試評論一個,計時,然后評論另一個。 此外,請確保您正在運行發布版本,而不是在調試器中。

暫無
暫無

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

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