有人可以解释这些结果吗? 我知道有重复的问题,但我还没有找到一个与我的结果得出相同结论的问题: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<Person>();
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<Person> people)
{
AddTwins(people, name, "");
}
private static void AddTwins(List<Person> 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;
}
}
}
}
}
答案 0 :(得分:16)
您永远不会执行LINQ
查询,只需创建它即可。您应该使用ToList
或ToArray
方法强制进行迭代,可能您不会得到不同的结果,因为LINQ
也使用foreach
循环。
修改:LINQ
需要更多时间,因为您正在迭代所有项目。但是在你的另外两个循环中,一旦找到匹配就会打破循环。尝试使用FirstOrDefault
代替Where
,您应该获得相同(或类似)的结果。
people.FirstOrDefault(p => p.Name == name);
答案 1 :(得分:1)
linq one没有时间,因为查询实际上从未被评估。
Linq is lazy对于大多数操作,在有人开始枚举结果之前,它实际上不会做任何事情。
如果您添加了
result.Count(); // add this line, query will be evaluated
linqTime = stopwatch.ElapsedMilliseconds;
stopwatch.Restart();
然后我很确定你对linq有一个非零结果。
答案 2 :(得分:0)
Sum必须在堆上存储列表枚举器的盒装实例,并使用该堆对象迭代列表,这显然很重要。内联foreach和for循环都避免了这种情况;前者因为List的公共GetEnumerator方法返回值类型。如果您在IEnumerable<Person>
变量中存储对人的引用,则foreach循环需要更长时间才能获得结果。
此外,linq必须为迭代器和委托传递给它的地方创建对象,并且它执行更多的空检查,因此如果任何参数为null,它可以抛出信息性异常。这可以解释linq代码所需的剩余额外时间。