I wrote another function that basically does the exact same thing, only 
tries to do it in as short a space as possible: here's what I got (and 
also benchmark times for the two of them)

I also tried splitting the original function into two seperate functions 
so it didn't have to do as many comparisons.

require 'benchmark'

class Hash
  #to avoid spamming more than necessary, see original email in thread 
for definition of to_params

  def to_params2(parent = '')
    self.keys.inject('') do |k, v|
      (self[v].is_a? Hash) ?
        (parent == '' ? k += self[v].to_params2(v.to_s) : k += 
self[v].to_params2(parent + "[#{v.to_s}]")) :
        (parent == '' ? k += "#{v}=#{self[v]}&" : k += 
"#{parent}[#{v}]=#{self[v]}&")
    end
  end

  def to_params3()
    ret = ''
    self.each_pair do |key, value|
      if value.is_a? Hash
        ret += value.to_params3_with_parent(key.to_s)
      else
        ret += "#{key}=#{value}&"
      end
    end
    return ret.chomp('&')
  end

  def to_params3_with_parent(parent)
    ret = ''
    self.each_pair do |key, value|
      if value.is_a? Hash
        ret += value.to_params3_with_parent(parent + "[#{key.to_s}]")
      else
        ret += "#{parent}[#{key}]=#{value}&"
      end
    end
    return ret.chomp('&')
  end

end

n = 100000
h = {:user => {:subuser => {:name => 'test'}, :name => 'test2'}, :name 
=> 'test3'}

Benchmark.bm do |x|
  x.report { n.times do; h.to_params; end }
  x.report { n.times do; h.to_params2; end }
  x.report { n.times do; h.to_params3; end }
end

Here's the results:

      user     system      total        real
  5.132000   0.000000   5.132000 (  5.174000) #original
  5.803000   0.000000   5.803000 (  5.844000) #with inject
  4.868000   0.000000   4.868000 (  4.880000) #split into two functions

Can anyone do better than the last one?

-- 
Posted via http://www.ruby-forum.com/.