title: Why do UInt16 arrays seem to add faster than int arrays?
body: <p>It seems that C# is faster at adding two arrays of <code>UInt16[]</code> than it is at adding two arrays of <code>int[]</code>. This makes no sense to me, since I would have assumed the arrays would be word-aligned, and thus <code>int[]</code> would require less work from the CPU, no?</p>
  
  <p>I ran the test-code below, and got the following results:</p>
  
  <pre><code>Int    for 1000 took 9896625613 tick (4227 msec)
  UInt16 for 1000 took 6297688551 tick (2689 msec)
  </code></pre>
  
  <p>The test code does the following:</p>
  
  <ol>
  <li>Creates two arrays named <code>a</code> and <code>b</code>, once.</li>
  <li>Fills them with random data, once.</li>
  <li>Starts a stopwatch.</li>
  <li>Adds <code>a</code> and <code>b</code>, item-by-item. This is done 1000 times.</li>
  <li>Stops the stopwatch.</li>
  <li>Reports how long it took.</li>
  </ol>
  
  <p>This is done for <code>int[] a, b</code> and for <code>UInt16 a,b</code>. And <strong>every</strong> time I run the code, the tests for the <code>UInt16</code> arrays take 30%-50% less time than the <code>int</code> arrays. Can you explain this to me?</p>
  
  <p>Here's the code, if you want to try if for yourself:</p>
  
  <pre><code>public static UInt16[] GenerateRandomDataUInt16(int length)
  {
      UInt16[] noise = new UInt16[length];
      Random random = new Random((int)DateTime.Now.Ticks);
      for (int i = 0; i &lt; length; ++i)
      {
          noise[i] = (UInt16)random.Next();
      }
  
      return noise;
  }
  
  public static int[] GenerateRandomDataInt(int length)
  {
      int[] noise = new int[length];
      Random random = new Random((int)DateTime.Now.Ticks);
      for (int i = 0; i &lt; length; ++i)
      {
          noise[i] = (int)random.Next();
      }
  
      return noise;
  }
  
  public static int[] AddInt(int[] a, int[] b)
  {
      int len = a.Length;
      int[] result = new int[len];
      for (int i = 0; i &lt; len; ++i)
      {
          result[i] = (int)(a[i] + b[i]);
      }
      return result;
  }
  
  public static UInt16[] AddUInt16(UInt16[] a, UInt16[] b)
  {
      int len = a.Length;
      UInt16[] result = new UInt16[len];
      for (int i = 0; i &lt; len; ++i)
      {
          result[i] = (ushort)(a[i] + b[i]);
      }
      return result;
  }
  
  
  public static void Main()
  {
      int count = 1000;
      int len = 128 * 6000;
  
      int[] aInt = GenerateRandomDataInt(len);
      int[] bInt = GenerateRandomDataInt(len);
  
      Stopwatch s = new Stopwatch();
      s.Start();
      for (int i=0; i&lt;count; ++i) 
      {
          int[] resultInt = AddInt(aInt, bInt);
      }
      s.Stop();
      Console.WriteLine("Int    for " + count 
                  + " took " + s.ElapsedTicks + " tick (" 
                  + s.ElapsedMilliseconds + " msec)");
  
      UInt16[] aUInt16 = GenerateRandomDataUInt16(len);
      UInt16[] bUInt16 = GenerateRandomDataUInt16(len);
  
      s = new Stopwatch();
      s.Start();
      for (int i=0; i&lt;count; ++i) 
      {
          UInt16[] resultUInt16 = AddUInt16(aUInt16, bUInt16);
      }
      s.Stop();
      Console.WriteLine("UInt16 for " + count 
                  + " took " + s.ElapsedTicks + " tick (" 
                  + s.ElapsedMilliseconds + " msec)");
  
  
  }
  </code></pre>