title: C# - For vs Foreach - Huge performance difference
body: <p>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?</p>
  
  <pre><code>  class Teste
  {
      public double Valor { get; set; }
  
      public Teste(double d)
      {
          Valor = d;
      }
  
      public override string ToString()
      {
          return "Teste: " + Valor;
      }
  }
  
    private static IEnumerable&lt;Teste&gt; GetTeste(double total)
      {
          for (int i = 1; i &lt;= 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=&gt;d.Valor), test);
          Console.WriteLine("------------");
          ForUpper(ieTeste.Select(d =&gt; d.Valor), test);
          Console.Read();
      }
  
      private static void ForUpper(IEnumerable&lt;double&gt; bigList, double find)
      {
          var start1 = DateTime.Now;
  
          double uppper = 0;
          for (int i = 0; i &lt; bigList.Count(); i++)
          {
              var toMatch = bigList.ElementAt(i);
              if (toMatch &gt;= find)
              {
                  uppper = toMatch;
                  break;
              }
          }
  
          var end1 = (DateTime.Now - start1).TotalMilliseconds;
  
          Console.WriteLine(end1 + " = " + uppper);
      }
  
      private static void ForeachUpper(IEnumerable&lt;double&gt; bigList, double find)
      {
          var start1 = DateTime.Now;
  
          double upper = 0;
          foreach (var toMatch in bigList)
          {
              if (toMatch &gt;= find)
              {
                  upper = toMatch;
                  break;
              }
          }
  
          var end1 = (DateTime.Now - start1).TotalMilliseconds;
  
          Console.WriteLine(end1 + " = " + upper);
      }
  </code></pre>
  
  <p>Thanks</p>