On Thu, 28 Dec 2006, Pit Capitain wrote: > Daniel Berger schrieb: >> I came across a technique for aliasing methods that I have never seen >> before [1] and was just too good to pass up. (...) > > Dan, this is a nice technique indeed (not new, but still nice), but it comes > with a performance penalty: > > class HashUsingAlias < Hash > alias :old_hset :[]= > > def []=(key, value) > self.old_hset(key, value) > end > end > > class HashUsingBind < Hash > hset = self.instance_method(:[]=) > > define_method(:[]=) do |key, value| > hset.bind(self).call(key, value) > end > end > > require "benchmark" > > def bm_report bm, title, hash_class > hash = hash_class.new > bm.report title do > 100_000.times do > hash[ 1 ] = 1 > end > end > end > > Benchmark.bmbm do |bm| > bm_report bm, "original", Hash > bm_report bm, "alias", HashUsingAlias > bm_report bm, "bind", HashUsingBind > end > > On my system, I get the following results: > > user system total real > original 0.062000 0.000000 0.062000 ( 0.062000) > alias 0.141000 0.000000 0.141000 ( 0.140000) > bind 0.656000 0.000000 0.656000 ( 0.657000) mine is slowest of all, however it preserves blocks: see if you can speed it up: harp:~ > cat a.rb class HashUsingAlias < Hash alias :old_hset :[]= def []=(key, value) self.old_hset(key, value) end end class HashUsingBind < Hash hset = self.instance_method(:[]=) define_method(:[]=) do |key, value| hset.bind(self).call(key, value) end end require 'override' class HashUsingOverride < Hash override('[]='){ def []=(k,v) super end } end require "benchmark" def bm_report bm, title, hash_class hash = hash_class.new bm.report title do 100_000.times do hash[ 1 ] = 1 end end end Benchmark.bmbm do |bm| bm_report bm, "original", Hash bm_report bm, "alias", HashUsingAlias bm_report bm, "bind", HashUsingBind bm_report bm, "override", HashUsingOverride end harp:~ > ruby a.rb Rehearsal -------------------------------------------- original 0.070000 0.000000 0.070000 ( 0.070856) alias 0.140000 0.000000 0.140000 ( 0.144095) bind 0.370000 0.000000 0.370000 ( 0.381127) override 0.470000 0.000000 0.470000 ( 0.476067) ----------------------------------- total: 1.050000sec user system total real original 0.070000 0.000000 0.070000 ( 0.072046) alias 0.150000 0.000000 0.150000 ( 0.144368) bind 0.390000 0.000000 0.390000 ( 0.388440) override 0.470000 0.000000 0.470000 ( 0.481620) harp:~ > cat override.rb class Module def child this = self @child ||= self.class.new @child.module_eval{ include this} @child end def has_child defined? @child and @child end def override m, &b this = self m = Module.new{ @m = this.instance_method m this.module_eval{ remove_method m rescue nil } module_eval <<-code def #{ m }(*a, &b) um = ObjectSpace._id2ref #{ @m.object_id } um.bind(self).call *a, &b end code child.module_eval &b if b } include(m.has_child ? m.child : m) end end -a -- if you find yourself slandering anybody, first imagine that your mouth is filled with excrement. it will break you of the habit quickly enough. - the dalai lama