title: Fast Enumeration slower than for-loop in nested enumeration (with test-results)?
body: <p>I know there are quite some topics that seem to be about the exact same thing, but I didn't find one that really was about what I wanted. </p>
  
  <p>So I was curious and wanted to compare the performance of Fast Enumeration to NSEnumerator and a for loop. (This is the part that is asked quite frequently)</p>
  
  <p>First I compared Fast Enumeration:</p>
  
  <pre><code>for(NSNumber *number in testArray)
  {
      assert(number);
  }
  </code></pre>
  
  <p>NSEnumerator:</p>
  
  <pre><code>NSEnumerator *enumerator = [testArray objectEnumerator];
  NSNumber *number;
  while (number = [enumerator nextObject]) 
  {
      assert(number);
  }
  </code></pre>
  
  <p>for Loop:</p>
  
  <pre><code>for(NSUInteger i = 0; i &lt; [testArray count]; i++)
  {
      NSNumber *number = [testArray objectAtIndex:i];
      assert(number);
  }
  </code></pre>
  
  <p>My <code>testArray</code> was an Array consisting of NSNumbers from 0 to 1,000,000 and I ran the tests 100 Times after each other and calculated the mean run time for each test. </p>
  
  <p>Also I ran them on my iPad 2</p>
  
  <p>Results: (mean time of all 100 runs)</p>
  
  <ul>
  <li><strong>0.042687s</strong> Fast Enumeration</li>
  <li><strong>0.582072s</strong> NSEnumerator</li>
  <li><strong>0.627318s</strong> for-loop</li>
  </ul>
  
  <p>As expected, Fast Enumeration is by far the fastest, and NSEnumerator is still a little bit faster than the for-loop, but this was for enumerating quit a large Array</p>
  
  <p>So here's the not so frequent Question:</p>
  
  <p><strong>Actually I was interested in something else: Enumeration in an array to compare each object with each other in the array</strong></p>
  
  <p>First attempt with a nested for-loop:</p>
  
  <pre><code>for(int i = 0; i &lt; [testArray count]-1; i++)
  {
      NSNumber *number = [testArray objectAtIndex:i];
      for(int j = i+1; j &lt; [testArray count]; j++)
      {
          NSNumber *innerLoopNumber = [testArray objectAtIndex:j];
          assert(innerLoopNumber);
          assert(number);
      }
  }
  </code></pre>
  
  <p>For these Tests I had to reduce the size of the array and the number of runs to get them done in a reasonable time, because number of iterations grows of course with O(n^2). 
  So I ran them with an array with 5.000 NSNumbers and repeated the tests 5 times.</p>
  
  <p>Result: <strong>7.360645s</strong> for 1 run</p>
  
  <p>So I thought, sure, fast Enumeration should be faster. But to achieve the triangular Pattern to avoid comparing each pair of elements two times, I had to mix Fast Enumeration in the outer loop with NSEnumerator in the inner loop</p>
  
  <pre><code>for(NSNumber *number in testArray)
  {
      NSEnumerator *reverseEnumterator = [testArray reverseObjectEnumerator];
      NSNumber *innerLoopNumber = reverseEnumterator.nextObject;
      while(innerLoopNumber &amp;&amp; ![innerLoopNumber isEqualToNumber:number])
      {
          innerLoopNumber = reverseEnumterator.nextObject;
          assert(innerLoopNumber);
          assert(number);
      }
  }
  </code></pre>
  
  <p>And to my surprise, this was much slower: <strong>18.086980s</strong> for 1 run</p>
  
  <p>I then tried a hybrid version as well, using Fast Enumeration for the outer loop and a for-loop for the inner one:</p>
  
  <pre><code>int counter = 0;
  for(NSNumber *number in testArray)
  {
      for(int j = counter +1; j &lt; [testArray count]; j++)
      {
          NSNumber *innerLoopNumber = [testArray objectAtIndex:j];
          assert(innerLoopNumber);
          assert(number);
      }
      counter++;
  }
  </code></pre>
  
  <p>Result: <strong>7.079600s</strong> for 1 Run</p>
  
  <p>Just slightly faster than the plain for-loop. </p>
  
  <p>the numbers in one place:</p>
  
  <ul>
  <li><strong>07.360645s</strong> for-Loop</li>
  <li><strong>07.079600s</strong> Hybrid</li>
  <li><strong>18.086980s</strong> Fast Enumeration</li>
  </ul>
  
  <p>So I wonder, why is that? Does Fast Enumeration only work well when it is "undisrupted", does the use of NSEnumerator interfere with Fast Enumeration? 
  Or am I just missing something and my Method is wrong?</p>