一尘不染

LINQ扩展方法的顺序不影响性能吗?

c#

我感到惊讶的是,无论是预先添加还是附加LINQ扩展方法,这都无关紧要。

经过测试Enumerable.FirstOrDefault

  1. hugeList.Where(x => x.Text.Contains("10000")).FirstOrDefault();
  2. hugeList.FirstOrDefault(x => x.Text.Contains("10000"));

    var hugeList = Enumerable.Range(1, 50000000)
    .Select(i => new { ID = i, Text = "Item" + i });
    

    var sw1 = new System.Diagnostics.Stopwatch();
    var sw2 = new System.Diagnostics.Stopwatch();

    sw1.Start();
    for(int i=0;i<1000;i++)
    hugeList.Where(x => x.Text.Contains(“10000”)).FirstOrDefault();
    sw1.Stop();

    sw2.Start();
    for(int i=0;i<1000;i++)
    hugeList.FirstOrDefault(x => x.Text.Contains(“10000”));
    sw2.Stop();

    var result1 = String.Format(“FirstOrDefault after: {0} FirstOrDefault before: {1}”, sw1.Elapsed, sw2.Elapsed);
    //result1: FirstOrDefault after: 00:00:03.3169683 FirstOrDefault before: 00:00:03.0463219

    sw2.Restart();
    for (int i = 0; i < 1000; i++)
    hugeList.FirstOrDefault(x => x.Text.Contains(“10000”));
    sw2.Stop();

    sw1.Restart();
    for (int i = 0; i < 1000; i++)
    hugeList.Where(x => x.Text.Contains(“10000”)).FirstOrDefault();
    sw1.Stop();

    var result2 = String.Format(“FirstOrDefault before: {0} FirstOrDefault after: {1}”, sw2.Elapsed, sw1.Elapsed);
    //result2: FirstOrDefault before: 00:00:03.6833079 FirstOrDefault after: 00:00:03.1675611

    //average after:3.2422647 before: 3.3648149 (all seconds)

我会猜想,Where由于必须先找到所有匹配的项,然后采用第一个,而在前面FirstOrDefault可以产生第一个找到的项,因此挂起起来会比较慢。

问: 有人可以解释为什么我走错了路吗?


阅读 281

收藏
2020-05-19

共1个答案

一尘不染

我猜想,将它放在前面会比较慢,因为它必须先找到所有匹配的项,然后采用第一个,然后使用FirstOrDefault可以产生第一个找到的项。有人可以解释为什么我走错了路吗?

您的路线不正确,因为您的第一条陈述完全不正确。Where不是 需要找到所有匹配的物品 之前
获取第一个匹配项。Where“按需”获取匹配项;如果您只要求第一个,则只会获取第一个。如果只要求前两个,则只会获取前两个。

乔恩·斯基特(Jon
Skeet)在舞台上表现不错。假设您有三个人。第一人称洗牌盒。第二个人有一件T恤,上面写着“卡片是红色的”。第三人称戳第二人说“给我第一张牌”。第二个人一遍又一遍地戳第一个人,
直到 第一个人交出红牌,第二个人随后将其递给第三人。第二个人没有理由继续戳第一个人。任务完成了!

现在,如果第二个人的T恤显示“按等级升序排列”,则情况将大为不同。现在,第二个人确实确实需要从第一人手中获得每张纸牌,以便在将第一张纸牌交给第三人之前找到卡组中最低的纸牌。

现在,这应该为您提供必要的直觉,以告诉您订单何时因性能原因而重要。“给我红牌,然后对它们进行排序”的最终结果与“对所有卡进行排序,然后给我红卡”的结果完全相同,但是前者的速度要快得多,因为您不必花任何时间对卡片进行排序。您将要丢弃的黑卡。

2020-05-19