C# – For vs Foreach – 巨大的性能差异

我正在对一个算法进行一些优化,该算法在给定的数组中找到大于X的最小数字,但随后ai偶然发现了一个奇怪的差异。 在下面的代码中,“ForeachUpper”在625ms结束,“ForUpper”结束,我相信,几个小时(疯狂地慢)。 为什么这样?

class Teste { public double Valor { get; set; } public Teste(double d) { Valor = d; } public override string ToString() { return "Teste: " + Valor; } } private static IEnumerable GetTeste(double total) { for (int i = 1; i d.Valor), test); Console.WriteLine("------------"); ForUpper(ieTeste.Select(d => d.Valor), test); Console.Read(); } private static void ForUpper(IEnumerable bigList, double find) { var start1 = DateTime.Now; double uppper = 0; for (int i = 0; i = find) { uppper = toMatch; break; } } var end1 = (DateTime.Now - start1).TotalMilliseconds; Console.WriteLine(end1 + " = " + uppper); } private static void ForeachUpper(IEnumerable bigList, double find) { var start1 = DateTime.Now; double upper = 0; foreach (var toMatch in bigList) { if (toMatch >= find) { upper = toMatch; break; } } var end1 = (DateTime.Now - start1).TotalMilliseconds; Console.WriteLine(end1 + " = " + upper); } 

谢谢

IEnumerable不可索引。

for循环的每次迭代中调用的Count()ElementAt()扩展方法都是O(n); 他们需要遍历集合来查找count或nth元素。

道德 :了解你的collections类型。

这种差异的原因是你的for循环将在每次迭代时执行bigList.Count() 。 在您的情况下,这非常昂贵,因为它将执行Select并迭代完整的结果集。

此外,您正在使用ElementAt ,它再次执行select并将其迭代到您提供的索引。