Yay for recursion :)

Recursion is usually inefficient in Ruby, but in this case with a small
number of elements it is actually faster. Nothing earth-shaking, but it
is fun to see recursion come out ahead once in a while in Ruby-land.
Yay!

Benchmark.ips do |x|
  array = ['updated_at desc', 'first_name asc', 'date desc']

  def parse_sort(field)
    attr_name, new_dir = field.to_s.split(/\s+/)
    "#{attr_name} #{new_dir}"
  end

  def recursive_add(array)
    return [] if array.empty?
    [parse_sort(array[0])] + recursive_add(array.drop 1)
  end

  def inject_add(array)
    array.inject([]) { |a, field| a + [parse_sort(field)] }
  end

  def inject_append(array)
    array.inject([]) { |a, field| a << parse_sort(field) }
  end

  def each_with_object_append(array)
    array.each_with_object([]) { |field, a| a << parse_sort(field) }
  end

  x.report('recursive +') do |times|
    i = 0
    while i < times
      recursive_add(array)
      i += 1
    end
  end

  x.report('inject +') do |times|
    i = 0
    while i < times
      inject_add(array)
      i += 1
    end
  end

  x.report('inject <<') do |times|
    i = 0
    while i < times
      inject_append(array)
      i += 1
    end
  end

  x.report('each_with_object <<') do |times|
    i = 0
    while i < times
      each_with_object_append(array)
      i += 1
    end
  end

  x.compare!
end

Base case 1 element (array = ['updated_at desc’]):

∴ rake benchmarks:inject_versus_recursive
Calculating -------------------------------------
recursive +    12.732k i/100ms
inject +    11.834k i/100ms
inject <<    12.096k i/100ms
each_with_object <<    12.535k i/100ms
-------------------------------------------------
recursive +    361.342k (±11.6%) i/s -      1.782M
inject +    275.680k (±10.8%) i/s -      1.373M
inject <<    330.712k (± 9.1%) i/s -      1.645M
each_with_object <<    345.253k (± 8.1%) i/s -      1.717M

Comparison:
recursive +:   361341.9 i/s
each_with_object <<:   345253.4 i/s - 1.05x slower
inject <<:   330712.3 i/s - 1.09x slower
inject +:   275679.5 i/s - 1.31x slower

With 3 elements (array = ['updated_at desc', 'first_name asc', 'date
desc']):

∴ rake benchmarks:inject_versus_recursive
Calculating -------------------------------------
recursive +     8.590k i/100ms
inject +     8.292k i/100ms
inject <<     8.776k i/100ms
each_with_object <<     8.665k i/100ms
-------------------------------------------------
recursive +    151.233k (± 2.8%) i/s -    755.920k
inject +    135.586k (± 4.3%) i/s -    679.944k
inject <<    144.773k (± 5.8%) i/s -    728.408k
each_with_object <<    147.728k (± 5.6%) i/s -    736.525k

Comparison:
recursive +:   151233.3 i/s
each_with_object <<:   147727.8 i/s - 1.02x slower
inject <<:   144772.9 i/s - 1.04x slower
inject +:   135586.4 i/s - 1.12x slower