ruby array internals

unshift is O(N^2) in my ruby1.9 .

$ /usr/bin/time ruby -e 'n=100000;l=[];(1..n).each{|i| l.push(i);}'
        0.03 real         0.02 user         0.00 sys
$ /usr/bin/time ruby -e 'n=100000;l=[];(1..n).each{|i| l.unshift(i);}'
        3.15 real         3.11 user         0.01 sys
$ /usr/bin/time ruby -e 'n=200000;l=[];(1..n).each{|i| l.unshift(i);}'
       12.96 real        12.85 user         0.03 sys
$ ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.3.0]

They're growable arrays which "grow at the end".

shift is O(1), unshift is O(n) and accessing by index is O(1). To the best of my knowledge this holds true for all ruby implementations, but it definitely does in MRI.

UPDATE: After this answer was originally written, Ruby was enhanced to make unshift amortized O(1). The enhanced array is in Ruby 2.0.0 and later, making shift, unshift, push, and pop all O(1) or amortized O(1).

Tags:

Arrays

Ruby