C# - For vs Foreach - 巨大的性能差异 [英] C# - For vs Foreach - Huge performance difference

查看:29
本文介绍了C# - For vs Foreach - 巨大的性能差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在对一种算法进行一些优化,该算法在给定的数组中找到大于 X 的最小数字,但随后我偶然发现了一个奇怪的差异.在下面的代码中,ForeachUpper"以 625 毫秒结束,而ForUpper"以几个小时结束(我相信是慢得多).为什么会这样?

i was making some optimizations to an algorithm that finds the smallest number that is bigger than X, in a given array, but then a i stumbled on a strange difference. On the code bellow, the "ForeachUpper" ends in 625ms, and the "ForUpper" ends in, i believe, a few hours (insanely slower). Why so?

  class Teste
{
    public double Valor { get; set; }

    public Teste(double d)
    {
        Valor = d;
    }

    public override string ToString()
    {
        return "Teste: " + Valor;
    }
}

  private static IEnumerable<Teste> GetTeste(double total)
    {
        for (int i = 1; i <= total; i++)
        {
            yield return new Teste(i);
        }
    }
    static void Main(string[] args)
    {
        int total = 1000 * 1000*30 ;
        double test = total/2+.7;

        var ieTeste = GetTeste(total).ToList();


        Console.WriteLine("------------");

        ForeachUpper(ieTeste.Select(d=>d.Valor), test);
        Console.WriteLine("------------");
        ForUpper(ieTeste.Select(d => d.Valor), test);
        Console.Read();
    }

    private static void ForUpper(IEnumerable<double> bigList, double find)
    {
        var start1 = DateTime.Now;

        double uppper = 0;
        for (int i = 0; i < bigList.Count(); i++)
        {
            var toMatch = bigList.ElementAt(i);
            if (toMatch >= find)
            {
                uppper = toMatch;
                break;
            }
        }

        var end1 = (DateTime.Now - start1).TotalMilliseconds;

        Console.WriteLine(end1 + " = " + uppper);
    }

    private static void ForeachUpper(IEnumerable<double> 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);他们需要遍历集合以找到计数或第 n 个元素.

The Count() and ElementAt() extension methods that you call in every iteration of your for loop are O(n); they need to loop through the collection to find the count or the nth element.

道德:了解您的收藏类型.

这篇关于C# - For vs Foreach - 巨大的性能差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆