LINQ vs foreach vs性能测试结果

有人可以解释这些结果吗? 我知道有一些重复的问题,但我还没有找到一个与我的结果得出相同结论的问题:o

using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SpeedTest { class Person { public Person(string name) { this.Name = name; } public string Name { get; set; } } class Program { static void Main(string[] args) { var people = new List(); AddTwins("FRANCISCO", people); var stopwatch = new Stopwatch(); string name = "OCSICNARF"; long linqTime = 0L; long foreachTime = 0L; long forTime = 0L; stopwatch.Start(); Person person0; var result = from person in people where person.Name == name select person; person0 = result.First(); linqTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); Person person1; foreach (Person p in people) { if (p.Name == name) { person1 = p; break; } } foreachTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); Person person2; for (int i = 0; i < people.Count; i++) { if (people[i].Name == name) { person2 = people[i]; break; } } forTime = stopwatch.ElapsedMilliseconds; stopwatch.Stop(); Console.WriteLine(string.Format("LINQ took {0}ms", linqTime)); Console.WriteLine(string.Format("FOREACH took {0}ms", foreachTime)); Console.WriteLine(string.Format("FOR took {0}ms", forTime)); } static void AddTwins(string name, List people) { AddTwins(people, name, ""); } private static void AddTwins(List people, string choices, string chosen) { if (choices.Length == 0) { people.Add(new Person(chosen)); } else { for (int i = 0; i < choices.Length; i++) { // choose char c = choices[i]; string choose1 = choices.Substring(0, i); string choose2 = choices.Substring(i + 1); choices = choose1 + choose2; // explore AddTwins(people, choices, chosen + c); // Unchoose string unchoose1 = choices.Substring(0, i); string unchoose2 = choices.Substring(i); choices = unchoose1 + c + unchoose2; } } } } } 

在此处输入图像描述

您永远不会执行LINQ查询,只需创建它。 您应该使用ToListToArray方法强制进行迭代,可能您不会得到不同的结果,因为LINQ使用foreach循环。

编辑LINQ需要更多时间,因为您正在迭代所有项目。 但是在你的另外两个循环中,你会在找到匹配后立即打破循环。 尝试使用FirstOrDefault而不是Where ,你应该得到相同(或类似)的结果。

 people.FirstOrDefault(p => p.Name == name); 

linq one没有时间,因为查询从未被实际评估过

Linq对于大多数操作来说都很懒惰 ,除非有人开始枚举结果,否则它实际上不会做任何事情。

如果你加了

 result.Count(); // add this line, query will be evaluated linqTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); 

那么我很确定你的linq非零结果。

Sum必须在堆上存储列表枚举器的盒装实例,并使用该堆对象迭代列表,这显然很重要。 内联foreach和for循环都避免了这种情况; 前者因为List的公共GetEnumerator方法返回值类型。 如果在IEnumerable变量中存储对人的引用,则foreach循环需要更长的时间才能获得结果。

此外,linq必须为迭代器和委托传递给它的地方创建对象,并且它执行更多的空检查,因此如果任何参数为null,它可以抛出信息exception。 这可以解释linq代码所需的剩余额外时间。