Ну, у меня была идея (та же идея, что и у sawa), и я решил, что хочу знать, было ли это улучшением. Вот результаты тестов:
params = {'puppies' => 'cute',
'dinosaurs' => 'angry',
'kittens' => 'kill them all',
'wat' => 4}
Benchmark.bm do |x|
x.report(".each"){10000.times{query = {}; params.each{ |k,v| query[k.singularize] = v }}}
x.report("Hash"){10000.times{query = Hash[params.map{|k, v| [k.singularize, v]}]}}
end
И результат:
user system total real
.each 3.850000 0.390000 4.240000 ( 4.260567)
Hash 3.910000 0.400000 4.310000 ( 4.402304)
Так что очень небольшая разница, хотя Hash - это противоположность улучшения, к сожалению - если производительность была проблемой для вас.
Я по-прежнему склонен использовать формат Hash[]
только потому, что мне нравится, как работает .map
... но .map
должен циклически проходить через каждый отдельный элемент, чтобы он не отличался.
EDIT:
Я пошел с предложением комментария сделать один действительно большой хэш вместо крошечного 10 000 раз. Вот результаты:
myhash = {}
20000.times do |i|
myhash[i.to_s * 2 + 's'] = i
end
Benchmark.bm do |x|
x.report(".each"){query = {}; myhash.each{|k,v| query[k.singularize] = v}}
x.report("Hash"){query = Hash[myhash.map{|k,v| [k.singularize, v]}]}
end
Результаты:
user system total real
.each 1.980000 0.110000 2.090000 ( 2.100811)
Hash 2.040000 0.140000 2.180000 ( 2.176588)
Редактировать 2: Кредит идет в пилу для этого третьего метода:
Benchmark.bm do |x|
x.report(".each"){query = {}; myhash.each{|k,v| query[k.singularize] = v}}
x.report("Hash"){query = Hash[myhash.map{|k,v| [k.singularize, v]}]}
x.report("with_object"){query = myhash.each_with_object({}){|(k, v), h| h[k.singularize] = v}}
end
user system total real
.each 2.050000 0.110000 2.160000 ( 2.174315)
Hash 2.070000 0.110000 2.180000 ( 2.187600)
with_object 2.100000 0.110000 2.210000 ( 2.207763)
Если вы (или кто-то другой) сможете найти способ изменить каждое значение на месте, я подозреваю, что это будет самый быстрый способ сделать это:
params.each{|arr| arr[0].singularize!}
Но вы не можете этого сделать, потому что
singularize!
не определено, а
- при попытке сделать это:
params.each{|arr| arr[0].gsub!('s', '')}
Вы получаете ошибку:
TypeError: can't modify frozen string
Я бы просто придерживался оригинальной версии: p