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/.