簡體   English   中英

為什么LINQ中的LastOrDefault(謂詞)比FirstOrDefault(謂詞)更快

[英]Why is LastOrDefault(predicate) in LINQ faster than FirstOrDefault(predicate)

介紹

在測試今天與某些LinQ函數的性能差異時,我注意到, LastOrDefault(predicate)幾乎總是比FirstOrDefault(predicate)更快,這讓我有點興趣,所以我寫了一些測試用例,以測試兩個函數相互對立。

我創建了一個1到1 mil的integer數值列表,如下所示:

List<int> l = new List<int>();
for (int i = 1; i <= 1000000; i++)
  {
    l.Add(i);
  }

然后寫了2個方法first()last()

 static void first(List<int> l)
{
  int e = l.FirstOrDefault(x => x == 500000);
  int z = l.FirstOrDefault(x => x == 500000);
  int d = l.FirstOrDefault(x => x == 500000);
  int v = l.FirstOrDefault(x => x == 500000);
  int f = l.FirstOrDefault(x => x == 500000);
}

我把一個for循環運行1000次,在最后一次迭代后設置一個條件停止的斷點,但在我測試的每個單一情況下, LastOrDefault更快。

測試用例

  • 兩者都設置為列表中間的元素( LastOrDefault幾乎快了兩倍)
  • 兩者都設置為列表中具有相同距離的元素(如250k和750k) - LastOrDefault再次更快
  • 切換我的方法調用的順序Last()First()之前調用Last() First() ) - 沒有區別
  • 使用自己的列表運行它們而不是在同一列表上運行它們(再次沒有區別)
  • 運行一個,關閉應用程序,重新打開,運行另一個(仍然LastOrDefault更快)
  • 將謂詞設置為元素,不在列表中(仍然相同)
  • 將謂詞更改為multipe eligable對象(仍然相同)
  • 創建一個降序列表而不是一個升序列表(沒有區別)

    .Net核心版:3.0

由於調試器可能不准確,我再次嘗試使用此代碼:

  Console.WriteLine(DateTime.Now + ":" + DateTime.Now.Millisecond);
  for (int i = 0; i < 1000; i++)
  {
    first(l);
  }
  Console.WriteLine(DateTime.Now + ":" + DateTime.Now.Millisecond);
  for (int i = 0; i < 1000; i++)
  {
    last(l);
  }
  Console.WriteLine(DateTime.Now + ":" + DateTime.Now.Millisecond);

對於FirstOrDefault ,它還返回34秒,為LastOrDefault返回23秒

在此輸入圖像描述

在我的所有測試用例中, LastOrDefault如何比FirstOrDefault快得多?

steve16351在刪除的評論中指出,在.NET Core中, Last有以下優化:

if (source is IList<TSource> list)
{
    for (int i = list.Count - 1; i >= 0; --i)
    {
        TSource result = list[i];
        if (predicate(result))
        {
            found = true;
            return result;
        }
    }
}

First沒有,最終運行:

foreach (TSource element in source)
{
    if (predicate(element))
    {
        found = true;
        return element;
    }
}

索引器對列表元素的訪問很可能比使用foreach和迭代器更快。 相比之下,.NET Standard沒有針對Last進行此優化,而是遍歷完整輸入,而Last運行速度比First低得多。

我嘗試執行ExecuteFirstExecuteLast甚至更改它們的執行順序,而LastOrDefault總是超過FirstOrDefault

class Program
{
    static void Main(string[] args)
    {
        List<int> numbers = new List<int>();
        for (int i = 1; i <= 1000000; i++)
        {
            numbers.Add(i);
        }

        for (int i = 1; i <= 100; i++)
        {
            Stopwatch stopwatch = new Stopwatch();
            ExecuteFirst(ref stopwatch, ref numbers);
            stopwatch.Reset();
            ExecuteLast(ref stopwatch, ref numbers);
        }

        for (int i = 1; i <= 100; i++)
        {
            Stopwatch stopwatch = new Stopwatch();
            ExecuteLast(ref stopwatch, ref numbers);
            stopwatch.Reset();
            ExecuteFirst(ref stopwatch, ref numbers);
        }
    }

    private static void ExecuteFirst(ref Stopwatch stopwatch, ref List<int> numbers)
    {
        stopwatch.Start();
        int first = numbers.FirstOrDefault(x => x == 500000);
        stopwatch.Stop();
        Console.WriteLine("First: " + stopwatch.Elapsed);
    }

    private static void ExecuteLast(ref Stopwatch stopwatch, ref List<int> numbers)
    {
        stopwatch.Start();
        int last = numbers.LastOrDefault(x => x == 500000);
        stopwatch.Stop();
        Console.WriteLine("Last: " + stopwatch.Elapsed);
    }
}

輸出ExecuteFirst then ExecuteLast版本:

 First: 00:00:00.0056298 Last: 00:00:00.0089494 First: 00:00:00.0039494 Last: 00:00:00.0084491 First: 00:00:00.0041225 Last: 00:00:00.0087664 First: 00:00:00.0039685 Last: 00:00:00.0083576 First: 00:00:00.0064472 Last: 00:00:00.0109716 First: 00:00:00.0041366 Last: 00:00:00.0111575 First: 00:00:00.0039746 Last: 00:00:00.0085590 First: 00:00:00.0040453 Last: 00:00:00.0083751 First: 00:00:00.0057352 Last: 00:00:00.0090655 First: 00:00:00.0041225 Last: 00:00:00.0081635 First: 00:00:00.0042336 Last: 00:00:00.0085277 First: 00:00:00.0038742 Last: 00:00:00.0088863 First: 00:00:00.0039309 Last: 00:00:00.0141321 First: 00:00:00.0044766 Last: 00:00:00.0088888 First: 00:00:00.0044096 Last: 00:00:00.0147227 First: 00:00:00.0042950 Last: 00:00:00.0177956 First: 00:00:00.0064265 Last: 00:00:00.0158906 First: 00:00:00.0051914 Last: 00:00:00.0177836 First: 00:00:00.0067148 Last: 00:00:00.0123487 First: 00:00:00.0045096 Last: 00:00:00.0113824 First: 00:00:00.0040213 Last: 00:00:00.0145903 First: 00:00:00.0061554 Last: 00:00:00.0123555 First: 00:00:00.0047815 Last: 00:00:00.0119132 First: 00:00:00.0055103 Last: 00:00:00.0141871 First: 00:00:00.0069865 Last: 00:00:00.0115481 First: 00:00:00.0052736 Last: 00:00:00.0167697 First: 00:00:00.0062566 Last: 00:00:00.0111363 First: 00:00:00.0051245 Last: 00:00:00.0120161 First: 00:00:00.0044649 Last: 00:00:00.0086359 First: 00:00:00.0039902 Last: 00:00:00.0089326 First: 00:00:00.0070409 Last: 00:00:00.0093965 First: 00:00:00.0047403 Last: 00:00:00.0143759 First: 00:00:00.0052523 Last: 00:00:00.0105465 First: 00:00:00.0072541 Last: 00:00:00.0113418 First: 00:00:00.0064120 Last: 00:00:00.0139322 First: 00:00:00.0062902 Last: 00:00:00.0173657 First: 00:00:00.0068329 Last: 00:00:00.0163935 First: 00:00:00.0056465 Last: 00:00:00.0100116 First: 00:00:00.0057379 Last: 00:00:00.0084148 First: 00:00:00.0058303 Last: 00:00:00.0167930 First: 00:00:00.0065232 Last: 00:00:00.0100014 First: 00:00:00.0039309 Last: 00:00:00.0093778 First: 00:00:00.0047291 Last: 00:00:00.0133724 First: 00:00:00.0044344 Last: 00:00:00.0095120 First: 00:00:00.0044793 Last: 00:00:00.0083334 First: 00:00:00.0048849 Last: 00:00:00.0091849 First: 00:00:00.0042633 Last: 00:00:00.0095615 First: 00:00:00.0074706 Last: 00:00:00.0081830 First: 00:00:00.0046968 Last: 00:00:00.0086369 First: 00:00:00.0055665 Last: 00:00:00.0088337 First: 00:00:00.0045883 Last: 00:00:00.0112508 First: 00:00:00.0078855 Last: 00:00:00.0149504 First: 00:00:00.0065615 Last: 00:00:00.0102155 First: 00:00:00.0046303 Last: 00:00:00.0104928 First: 00:00:00.0063564 Last: 00:00:00.0119335 First: 00:00:00.0048461 Last: 00:00:00.0092795 First: 00:00:00.0042306 Last: 00:00:00.0090954 First: 00:00:00.0042236 Last: 00:00:00.0090376 First: 00:00:00.0039102 Last: 00:00:00.0087163 First: 00:00:00.0047897 Last: 00:00:00.0093651 First: 00:00:00.0051779 Last: 00:00:00.0101453 First: 00:00:00.0041795 Last: 00:00:00.0086312 First: 00:00:00.0039371 Last: 00:00:00.0087337 First: 00:00:00.0048348 Last: 00:00:00.0114352 First: 00:00:00.0049419 Last: 00:00:00.0134430 First: 00:00:00.0063191 Last: 00:00:00.0096597 First: 00:00:00.0041087 Last: 00:00:00.0100510 First: 00:00:00.0055977 Last: 00:00:00.0122221 First: 00:00:00.0046453 Last: 00:00:00.0097579 First: 00:00:00.0050965 Last: 00:00:00.0108959 First: 00:00:00.0061811 Last: 00:00:00.0093178 First: 00:00:00.0060297 Last: 00:00:00.0085977 First: 00:00:00.0040451 Last: 00:00:00.0114430 First: 00:00:00.0046424 Last: 00:00:00.0118572 First: 00:00:00.0064396 Last: 00:00:00.0147170 First: 00:00:00.0052414 Last: 00:00:00.0108874 First: 00:00:00.0045109 Last: 00:00:00.0082625 First: 00:00:00.0044640 Last: 00:00:00.0136483 First: 00:00:00.0049840 Last: 00:00:00.0087787 First: 00:00:00.0049482 Last: 00:00:00.0138222 First: 00:00:00.0055885 Last: 00:00:00.0109636 First: 00:00:00.0052437 Last: 00:00:00.0130392 First: 00:00:00.0053844 Last: 00:00:00.0103824 First: 00:00:00.0062271 Last: 00:00:00.0125599 First: 00:00:00.0043152 Last: 00:00:00.0091548 First: 00:00:00.0059537 Last: 00:00:00.0125432 First: 00:00:00.0057340 Last: 00:00:00.0099097 First: 00:00:00.0052127 Last: 00:00:00.0087050 First: 00:00:00.0045914 Last: 00:00:00.0095816 First: 00:00:00.0065290 Last: 00:00:00.0090501 First: 00:00:00.0045474 Last: 00:00:00.0108880 First: 00:00:00.0054650 Last: 00:00:00.0092074 First: 00:00:00.0042946 Last: 00:00:00.0129336 First: 00:00:00.0045581 Last: 00:00:00.0172552 First: 00:00:00.0058246 Last: 00:00:00.0080876 First: 00:00:00.0040249 Last: 00:00:00.0112583 First: 00:00:00.0047926 Last: 00:00:00.0085989 First: 00:00:00.0045357 Last: 00:00:00.0088068 First: 00:00:00.0039247 Last: 00:00:00.0094145 First: 00:00:00.0039182 Last: 00:00:00.0085856 

輸出ExecuteLast then ExecuteFirst版本:

 Last: 00:00:00.0087140 First: 00:00:00.0045242 Last: 00:00:00.0082524 First: 00:00:00.0040122 Last: 00:00:00.0081924 First: 00:00:00.0039598 Last: 00:00:00.0081365 First: 00:00:00.0041632 Last: 00:00:00.0087045 First: 00:00:00.0040455 Last: 00:00:00.0082440 First: 00:00:00.0041200 Last: 00:00:00.0082281 First: 00:00:00.0041470 Last: 00:00:00.0087138 First: 00:00:00.0039467 Last: 00:00:00.0082286 First: 00:00:00.0099966 Last: 00:00:00.0159285 First: 00:00:00.0059864 Last: 00:00:00.0103221 First: 00:00:00.0045370 Last: 00:00:00.0102541 First: 00:00:00.0042682 Last: 00:00:00.0081628 First: 00:00:00.0062049 Last: 00:00:00.0130017 First: 00:00:00.0046107 Last: 00:00:00.0146495 First: 00:00:00.0060628 Last: 00:00:00.0140509 First: 00:00:00.0042348 Last: 00:00:00.0087499 First: 00:00:00.0043035 Last: 00:00:00.0119328 First: 00:00:00.0053357 Last: 00:00:00.0095866 First: 00:00:00.0081749 Last: 00:00:00.0157497 First: 00:00:00.0065187 Last: 00:00:00.0165949 First: 00:00:00.0062613 Last: 00:00:00.0139213 First: 00:00:00.0058088 Last: 00:00:00.0121819 First: 00:00:00.0054371 Last: 00:00:00.0095390 First: 00:00:00.0070151 Last: 00:00:00.0110936 First: 00:00:00.0073251 Last: 00:00:00.0104844 First: 00:00:00.0058563 Last: 00:00:00.0131254 First: 00:00:00.0064146 Last: 00:00:00.0100039 First: 00:00:00.0045887 Last: 00:00:00.0102629 First: 00:00:00.0051754 Last: 00:00:00.0086035 First: 00:00:00.0041619 Last: 00:00:00.0104485 First: 00:00:00.0055513 Last: 00:00:00.0097863 First: 00:00:00.0047921 Last: 00:00:00.0097700 First: 00:00:00.0049790 Last: 00:00:00.0129902 First: 00:00:00.0049853 Last: 00:00:00.0090255 First: 00:00:00.0044574 Last: 00:00:00.0085991 First: 00:00:00.0061191 Last: 00:00:00.0144359 First: 00:00:00.0048091 Last: 00:00:00.0133516 First: 00:00:00.0056255 Last: 00:00:00.0084006 First: 00:00:00.0063759 Last: 00:00:00.0193624 First: 00:00:00.0062311 Last: 00:00:00.0176409 First: 00:00:00.0069601 Last: 00:00:00.0168154 First: 00:00:00.0069095 Last: 00:00:00.0099649 First: 00:00:00.0057600 Last: 00:00:00.0087139 First: 00:00:00.0040068 Last: 00:00:00.0085248 First: 00:00:00.0061416 Last: 00:00:00.0085084 First: 00:00:00.0043856 Last: 00:00:00.0089587 First: 00:00:00.0044830 Last: 00:00:00.0093276 First: 00:00:00.0043679 Last: 00:00:00.0110072 First: 00:00:00.0042437 Last: 00:00:00.0126469 First: 00:00:00.0042610 Last: 00:00:00.0112851 First: 00:00:00.0044525 Last: 00:00:00.0146068 First: 00:00:00.0067056 Last: 00:00:00.0126607 First: 00:00:00.0048659 Last: 00:00:00.0083654 First: 00:00:00.0062265 Last: 00:00:00.0097216 First: 00:00:00.0061381 Last: 00:00:00.0089756 First: 00:00:00.0042742 Last: 00:00:00.0106504 First: 00:00:00.0059941 Last: 00:00:00.0129825 First: 00:00:00.0052327 Last: 00:00:00.0086158 First: 00:00:00.0048668 Last: 00:00:00.0087767 First: 00:00:00.0040427 Last: 00:00:00.0097813 First: 00:00:00.0042703 Last: 00:00:00.0086771 First: 00:00:00.0051560 Last: 00:00:00.0097772 First: 00:00:00.0051117 Last: 00:00:00.0086385 First: 00:00:00.0050181 Last: 00:00:00.0092713 First: 00:00:00.0044719 Last: 00:00:00.0094507 First: 00:00:00.0041345 Last: 00:00:00.0090835 First: 00:00:00.0041929 Last: 00:00:00.0101841 First: 00:00:00.0045660 Last: 00:00:00.0132945 First: 00:00:00.0042977 Last: 00:00:00.0102504 First: 00:00:00.0041772 Last: 00:00:00.0087283 First: 00:00:00.0058613 Last: 00:00:00.0095019 First: 00:00:00.0058306 Last: 00:00:00.0098703 First: 00:00:00.0062143 Last: 00:00:00.0143740 First: 00:00:00.0058965 Last: 00:00:00.0146650 First: 00:00:00.0049196 Last: 00:00:00.0101419 First: 00:00:00.0045298 Last: 00:00:00.0096505 First: 00:00:00.0047797 Last: 00:00:00.0107579 First: 00:00:00.0059183 Last: 00:00:00.0126266 First: 00:00:00.0055267 Last: 00:00:00.0126165 First: 00:00:00.0054118 Last: 00:00:00.0120701 First: 00:00:00.0051365 Last: 00:00:00.0153770 First: 00:00:00.0053540 Last: 00:00:00.0153887 First: 00:00:00.0070967 Last: 00:00:00.0130810 First: 00:00:00.0058005 Last: 00:00:00.0099139 First: 00:00:00.0045073 Last: 00:00:00.0086909 First: 00:00:00.0050152 Last: 00:00:00.0092414 First: 00:00:00.0045098 Last: 00:00:00.0081899 First: 00:00:00.0039903 Last: 00:00:00.0088524 First: 00:00:00.0044292 Last: 00:00:00.0085165 First: 00:00:00.0041663 Last: 00:00:00.0079039 First: 00:00:00.0040911 Last: 00:00:00.0083395 First: 00:00:00.0041872 Last: 00:00:00.0093267 First: 00:00:00.0041617 Last: 00:00:00.0092689 First: 00:00:00.0042109 Last: 00:00:00.0088358 First: 00:00:00.0041233 Last: 00:00:00.0081352 First: 00:00:00.0046823 Last: 00:00:00.0085252 First: 00:00:00.0042007 Last: 00:00:00.0083383 First: 00:00:00.0041155 Last: 00:00:00.0096344 First: 00:00:00.0046664 Last: 00:00:00.0110845 First: 00:00:00.0047776 

暫無
暫無

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

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