From: "Florian Aßmann" Date: 2007-07-17T00:41:32+09:00 Subject: Re: clean nice way (hash) Robert Klemme schrieb: > 2007/7/16, Chris Carter : >> On 7/16/07, James Edward Gray II wrote: >> > On Jul 16, 2007, at 5:58 AM, hemant wrote: >> > >> > > a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem } >> > >> > I would write that as: >> > >> > a.inject(Hash.new) { |h, (k, v)| h.merge(k => v) } >> > >> > James Edward Gray II >> > >> > >> >> But that doesn't yield what he wanted... You could do >> a.inject(Hash.new){|h,(k,v)| h.merge(k => { 'name' => value})} > > Still it's inefficient because of all the small Hashes that are thrown > away immediately. The solution provided by hemant is better although > not as elegant. > > Kind regards > > robert > > Hi, I also tested a theory of mine, Hash#update does this ~20% faster than Hash#each: hash.update(hash) { |key, o_val, n_val| Hash['name' => o_val] } Thread ID: 101250 Total: 7.24 %self total self wait child calls name 66.16 7.24 4.79 0.00 2.45 1 Hash#update 33.84 2.45 2.45 0.00 0.00 456976 #[] 0.00 7.24 0.00 0.00 7.24 0 Global#[No method] hash.each { |key, value| hash[key] = Hash['name' => value] } Thread ID: 101250 Total: 9.28 %self total self wait child calls name 60.78 9.28 5.64 0.00 3.64 1 Hash#each 26.62 2.47 2.47 0.00 0.00 456976 #[] 12.61 1.17 1.17 0.00 0.00 456976 Hash#[]= 0.00 9.28 0.00 0.00 9.28 0 Global#[No method] As I profiled both cases I came across something I don't understand: When I do the profiling of both cases In the same Ruby process the later one always is slower as when I profile them seperatly, can somebody explain this? Regards Florian profile_update.rb: ================== require 'rubygems' require 'ruby-prof' puts 'Hash#update' hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value| hash[value] = value hash end result = RubyProf.profile do hash.update(hash) { |key, o_val, n_val| Hash['name' => o_val] } end RubyProf::FlatPrinter.new(result).print(STDOUT, 0) profile_update_first.rb: ======================== require 'rubygems' require 'ruby-prof' puts 'Hash#update' hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value| hash[value] = value hash end result = RubyProf.profile do hash.update(hash) { |key, o_val, n_val| Hash['name' => o_val] } end RubyProf::FlatPrinter.new(result).print(STDOUT, 0) puts 'Hash#each' hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value| hash[value] = value hash end result = RubyProf.profile do hash.each { |key, value| hash[key] = Hash['name' => value] } end RubyProf::FlatPrinter.new(result).print(STDOUT, 0) profile_each.rb: ================ require 'rubygems' require 'ruby-prof' puts 'Hash#each' hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value| hash[value] = value hash end result = RubyProf.profile do hash.each { |key, value| hash[key] = Hash['name' => value] } end RubyProf::FlatPrinter.new(result).print(STDOUT, 0) profile_each_first.rb: ====================== require 'rubygems' require 'ruby-prof' puts 'Hash#each' hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value| hash[value] = value hash end result = RubyProf.profile do hash.each { |key, value| hash[key] = Hash['name' => value] } end RubyProf::FlatPrinter.new(result).print(STDOUT, 0) puts 'Hash#update' hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value| hash[value] = value hash end result = RubyProf.profile do hash.update(hash) { |key, o_val, n_val| Hash['name' => o_val] } end RubyProf::FlatPrinter.new(result).print(STDOUT, 0)