Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Cleaning up the initialize method, improving performance #86

Closed
wants to merge 1 commit into from

2 participants

@krainboltgreene
  • Using friendlier variable names
  • Dropping for..in block for #each
  • Inlining if statement

I used this as a general benchmark:

require 'benchmark'

def new_ostruct_member(arg); end

def generate_data
  (0..1000).map do |i|
    {"#{'k' * rand(100)}#{i}" => "#{'v' * rand(100)}#{i}"}
  end.inject &:merge
end

hash = generate_data


report = Benchmark.bmbm do |x|
  x.report("old") { 1000.times {
    @table = {}
      for k,v in hash
        @table[k.to_sym] = v
        new_ostruct_member(k)
      end
  } }

  x.report("new") { 1000.times {
    @ntable = {}
    hash.each do |key, value|
      @ntable[key.to_sym] = value
      new_ostruct_member key
    end
  } }
end

puts "Is new result equal to old result? #{@table == @ntable}"
puts "New is #{report.map(&:to_s).map(&:split).map(&:last).map(&:to_f).inject(:/) * 100 - 100}% faster"

General speed improvement: ~27% faster, after fixing benchmark.

@krainboltgreene

Cleaned up the example to be a little more fair.

@krainboltgreene

Updated the benchmark again, using better tools.

@nurse nurse commented on the diff
lib/ostruct.rb
@@ -96,13 +96,11 @@ class OpenStruct
# p australia # -> <OpenStruct country="Australia" population=20000000>
#
def initialize(hash=nil)
- @table = {}
- if hash
- for k,v in hash
- @table[k.to_sym] = v
- new_ostruct_member(k)
- end
- end
+ @table ||= {}
@nurse Owner
nurse added a note

why ||=?

I've usually seen OpenStruct as a Parent class and if you want the "magic" to still work and fiddle with your class's initialize method you'll need to call super(). This way, if a developer does:

class AClass < OpenStruct
def initialize(args)
  @table = { color: 'red' }
  super(args)
end
end

The @table isn't wiped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 21, 2012
  1. Cleaning up the initialize method, improving performance

    Kurtis Rainbolt-Greene authored
This page is out of date. Refresh to see the latest.
Showing with 5 additions and 7 deletions.
  1. +5 −7 lib/ostruct.rb
View
12 lib/ostruct.rb
@@ -96,13 +96,11 @@ class OpenStruct
# p australia # -> <OpenStruct country="Australia" population=20000000>
#
def initialize(hash=nil)
- @table = {}
- if hash
- for k,v in hash
- @table[k.to_sym] = v
- new_ostruct_member(k)
- end
- end
+ @table ||= {}
@nurse Owner
nurse added a note

why ||=?

I've usually seen OpenStruct as a Parent class and if you want the "magic" to still work and fiddle with your class's initialize method you'll need to call super(). This way, if a developer does:

class AClass < OpenStruct
def initialize(args)
  @table = { color: 'red' }
  super(args)
end
end

The @table isn't wiped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ hash.each do |key, value|
+ @table[key.to_sym] = value
+ new_ostruct_member key
+ end if hash
end
# Duplicate an OpenStruct object members.
Something went wrong with that request. Please try again.