[ruby-cvs:59095] zzak:r51944 (trunk): * lib/ostruct.rb: Move method definitions for getter/setter to be lazy

zzak at ruby-lang.org zzak at ruby-lang.org
Sun Sep 27 01:05:53 JST 2015


zzak	2015-09-27 01:05:52 +0900 (Sun, 27 Sep 2015)

  New Revision: 51944

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51944

  Log:
    * lib/ostruct.rb: Move method definitions for getter/setter to be lazy
      Patch by @sferik in [GH-1033]: https://github.com/ruby/ruby/pull/1033
    
    Instead of defining two methods -- a reader and writer -- for each
    OpenStruct attribute when it is initialized, define them lazily, the
    first time either one is called. This adheres to the principle of "pay for
    use": methods that are never accessed are never defined. This optimization
    makes initialization an order of magnitude faster for objects with 100
    attributes. In the worst-case scenario, where every attribute is accessed,
    performance is no worse than it is today.
    
    Benchmark
    ---------
    require 'benchmark/ips'
    require 'ostruct'
    
    N = 100
    ATTRS = (:aa..:zz).take(N)
    HASH = Hash[ATTRS.map { |x| [x, x] }]
    
    def ostruct
      OpenStruct.new(HASH)
    end
    
    Benchmark.ips do |x|
      x.report('ostruct') { ostruct }
    end
    
    -------------------------------------------------
       before       2.279k (?\194?\177 8.8%) i/s -     11.395k
       after       24.702k (?\194?\17712.8%) i/s -    122.600k
    -------------------------------------------------

  Modified files:
    trunk/ChangeLog
    trunk/lib/ostruct.rb


More information about the ruby-cvs mailing list