title: Why is running "unique" faster on a data frame than a matrix in R?
body: <p>I've begun to believe that data frames hold no advantages over matrices, except for notational convenience.  However, I noticed this oddity when running <code>unique</code> on matrices and data frames: it seems to run faster on a data frame.</p>
  
  <pre><code>a   = matrix(sample(2,10^6,replace = TRUE), ncol = 10)
  b   = as.data.frame(a)
  
  system.time({
      u1 = unique(a)
  })
   user  system elapsed
  1.840   0.000   1.846
  
  
  system.time({
      u2 = unique(b)
  })
   user  system elapsed
  0.380   0.000   0.379
  </code></pre>
  
  <p>The timing results diverge even more substantially as the number of rows is increased.  So, there are two parts to this question.</p>
  
  <ol>
  <li><p>Why is this slower for a matrix?  It seems faster to convert to a data frame, run <code>unique</code>, and then convert back.  </p></li>
  <li><p>Is there any reason not to just wrap <code>unique</code> in <code>myUnique</code>, which does the conversions in part #1?</p></li>
  </ol>
  
  <hr>
  
  <p>Note 1. Given that a matrix is atomic, it seems that <code>unique</code> should be faster for a matrix, rather than slower.  Being able to iterate over fixed-size, contiguous blocks of memory should generally be faster than running over separate blocks of linked lists (I assume that's how data frames are implemented...).</p>
  
  <p>Note 2.  As demonstrated by the performance of <code>data.table</code>, running <code>unique</code> on a data frame or a matrix is a comparatively bad idea - see the answer by Matthew Dowle and the comments for relative timings.  I've migrated a lot of objects to data tables, and this performance is another reason to do so.  So although users should be well served to adopt data tables, for pedagogical / community reasons I'll leave the question open for now regarding the <em>why</em> does this take longer on the matrix objects.  The answers below address <em>where</em> does the time go, and <em>how else</em> can we get better performance (i.e. data tables).  The answer to <em>why</em> is close at hand - the code can be found via <code>unique.data.frame</code> and <code>unique.matrix</code>.  :)  An English explanation of what it's doing &amp; why is all that is lacking.</p>