我感到惊讶的是,无论是预先添加还是附加LINQ扩展方法,这都无关紧要。
经过测试Enumerable.FirstOrDefault:
Enumerable.FirstOrDefault
hugeList.Where(x => x.Text.Contains("10000")).FirstOrDefault();
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可以产生第一个找到的项,因此挂起起来会比较慢。
Where
FirstOrDefault
问: 有人可以解释为什么我走错了路吗?
我猜想,将它放在前面会比较慢,因为它必须先找到所有匹配的项,然后采用第一个,然后使用FirstOrDefault可以产生第一个找到的项。有人可以解释为什么我走错了路吗?
您的路线不正确,因为您的第一条陈述完全不正确。Where是 不是 需要找到所有匹配的物品 之前 获取第一个匹配项。Where“按需”获取匹配项;如果您只要求第一个,则只会获取第一个。如果只要求前两个,则只会获取前两个。
乔恩·斯基特(Jon Skeet)在舞台上表现不错。假设您有三个人。第一人称洗牌盒。第二个人有一件T恤,上面写着“卡片是红色的”。第三人称戳第二人说“给我第一张牌”。第二个人一遍又一遍地戳第一个人, 直到 第一个人交出红牌,第二个人随后将其递给第三人。第二个人没有理由继续戳第一个人。任务完成了!
现在,如果第二个人的T恤显示“按等级升序排列”,则情况将大为不同。现在,第二个人确实确实需要从第一人手中获得每张纸牌,以便在将第一张纸牌交给第三人之前找到卡组中最低的纸牌。
现在,这应该为您提供必要的直觉,以告诉您订单何时因性能原因而重要。“给我红牌,然后对它们进行排序”的最终结果与“对所有卡进行排序,然后给我红卡”的结果完全相同,但是前者的速度要快得多,因为您不必花任何时间对卡片进行排序。您将要丢弃的黑卡。