title: Why would I see ~20% speed increase using native code?
body: <p>Any idea why this code:</p>
  
  <pre><code>extern "C" __declspec(dllexport) void Transform(double x[], double y[], int iterations, bool forward)
  {
      long n, i, i1, j, k, i2, l, l1, l2;
      double c1, c2, tx, ty, t1, t2, u1, u2, z;
  
      /* Calculate the number of points */
      n = (long)pow((double)2, (double)iterations);
  
      /* Do the bit reversal */
      i2 = n &gt;&gt; 1;
      j = 0;
      for (i = 0; i &lt; n - 1; ++i)
      {
          if (i &lt; j)
          {
              tx = x[i];
              ty = y[i];
              x[i] = x[j];
              y[i] = y[j];
              x[j] = tx;
              y[j] = ty;
          }
          k = i2;
          while (k &lt;= j)
          {
              j -= k;
              k &gt;&gt;= 1;
          }
          j += k;
      }
  
      /* Compute the FFT */
      c1 = -1.0; 
      c2 = 0.0;
      l2 = 1;
      for (l = 0; l &lt; iterations; ++l)
      {
          l1 = l2;
          l2 &lt;&lt;= 1;
          u1 = 1; 
          u2 = 0;
          for (j = 0; j &lt; l1; j++) 
          {
              for (i = j; i &lt; n; i += l2) 
              {
                  i1 = i + l1;
                  t1 = u1 * x[i1] - u2 * y[i1];
                  t2 = u1 * y[i1] + u2 * x[i1];
                  x[i1] = x[i] - t1; 
                  y[i1] = y[i] - t2;
                  x[i] += t1;
                  y[i] += t2;
              }
              z = u1 * c1 - u2 * c2;
              u2 = u1 * c2 + u2 * c1;
              u1 = z;
          }
          c2 = sqrt((1.0 - c1) / 2.0);
          if (forward) 
              c2 = -c2;
          c1 = sqrt((1.0 + c1) / 2.0);
      }
  
      /* Scaling for forward transform */
      if (forward)
      {
          for (i = 0; i &lt; n; ++i)
          {
              x[i] /= n;
              y[i] /= n;
          }
      }
  }
  </code></pre>
  
  <p>runs 20% faster than this code?</p>
  
  <pre><code>public static void Transform(DataSet data, Direction direction)
  {
      double[] x = data.Real;
      double[] y = data.Imag;
      data.Direction = direction;
      data.ExtremeImag = 0.0;
      data.ExtremeReal = 0.0;
      data.IndexExtremeImag = 0;
      data.IndexExtremeReal = 0;
  
      long n, i, i1, j, k, i2, l, l1, l2;
      double c1, c2, tx, ty, t1, t2, u1, u2, z;
  
      /* Calculate the number of points */
      n = (long)Math.Pow(2, data.Iterations);
  
      /* Do the bit reversal */
      i2 = n &gt;&gt; 1;
      j = 0;
      for (i = 0; i &lt; n - 1; ++i)
      {
          if (i &lt; j)
          {
              tx = x[i];
              ty = y[i];
              x[i] = x[j];
              y[i] = y[j];
              x[j] = tx;
              y[j] = ty;
          }
          k = i2;
          while (k &lt;= j)
          {
              j -= k;
              k &gt;&gt;= 1;
          }
          j += k;
      }
  
      /* Compute the FFT */
      c1 = -1.0; 
      c2 = 0.0;
      l2 = 1;
      for (l = 0; l &lt; data.Iterations; ++l)
      {
          l1 = l2;
          l2 &lt;&lt;= 1;
          u1 = 1; 
          u2 = 0;
          for (j = 0; j &lt; l1; j++) 
          {
              for (i = j; i &lt; n; i += l2) 
              {
                  i1 = i + l1;
                  t1 = u1 * x[i1] - u2 * y[i1];
                  t2 = u1 * y[i1] + u2 * x[i1];
                  x[i1] = x[i] - t1; 
                  y[i1] = y[i] - t2;
                  x[i] += t1;
                  y[i] += t2;
              }
              z = u1 * c1 - u2 * c2;
              u2 = u1 * c2 + u2 * c1;
              u1 = z;
          }
          c2 = Math.Sqrt((1.0 - c1) / 2.0);
          if (direction == Direction.Forward) 
              c2 = -c2;
          c1 = Math.Sqrt((1.0 + c1) / 2.0);
      }
  
      /* Scaling for forward transform */
      if (direction == Direction.Forward)
      {
          for (i = 0; i &lt; n; ++i)
          {
              x[i] /= n;
              y[i] /= n;
              if (Math.Abs(x[i]) &gt; data.ExtremeReal)
              {
                  data.ExtremeReal = x[i];
                  data.IndexExtremeReal = (int)i;
              }
              if (Math.Abs(y[i]) &gt; data.ExtremeImag)
              {
                  data.ExtremeImag = y[i];
                  data.IndexExtremeImag = (int)i;
              }
          }
      }
  }
  </code></pre>
  
  <p><a href="http://www.rghware.com/fft.png" rel="noreferrer">FFT http://www.rghware.com/fft.png</a></p>
  
  <p>I created the drop in CPU seen in the middle of the graph by selecting the “Native DLL FFT” in my app:</p>
  
  <p><a href="http://www.rghware.com/InstrumentTuner.zip" rel="noreferrer">http://www.rghware.com/InstrumentTuner.zip</a> (source code)</p>
  
  <p>I think this will run on most PCs.  You’ll need to have DirectX installed.  I had some issues using the capture settings for certain hardware.  The capture settings were supposed to be configurable, but the app’s development has been sidetracked by this interesting find.</p>
  
  <p>Anyway, why I’m seeing a 20% increase in speed using the native code?  This seems to fly in the face of some of the assumptions I previously had.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>After converting the function to an unsafe method and fixing the long/int issue.  The new unsafe method actually runs faster than the native method (pretty cool).</p>
  
  <p><a href="http://www.rghware.com/profile.png" rel="noreferrer">Profile http://www.rghware.com/profile.png</a></p>
  
  <p>It's obvious that the array bound checking is the cause of the 20% slow down in this FFT method.  Due to it's nature, the for-loops in this method cannot be optimized.</p>
  
  <p>Thanks everyone for the help.</p>