簡體   English   中英

C# - For vs Foreach - 巨大的性能差異

[英]C# - For vs Foreach - Huge performance difference

我正在對一個算法進行一些優化,該算法在給定的數組中找到大於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<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<T>不可索引。

for循環的每次迭代中調用的Count()ElementAt()擴展方法都是O(n); 他們需要循環遍歷集合以查找計數或第n個元素。

道德 :了解你的收藏類型。

這種差異的原因是你的for循環將在每次迭代時執行bigList.Count() 在您的情況下,這非常昂貴,因為它將執行Select並迭代完整的結果集。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM