Skip to content

Instantly share code, notes, and snippets.

@gwilczynski
Created March 2, 2017 23:23
Show Gist options
  • Save gwilczynski/f402aa8aed496da16af5cd2cd9cbe822 to your computer and use it in GitHub Desktop.
Save gwilczynski/f402aa8aed496da16af5cd2cd9cbe822 to your computer and use it in GitHub Desktop.
Please don’t hate OpenStruct
require 'benchmark'
require 'benchmark/ips'
require 'ostruct'
require 'active_model'
BillingAddressStruct = Struct.new(:street, :city, :zipcode, :country, :state)
BillingAddressOpenStruct = OpenStruct
BillingAddressStructFromHash = Struct.new(:street, :city, :zipcode, :country, :state) do
def self.from_hash(attributes)
instance = new
attributes.each do |key, value|
instance[key] = value
end
instance
end
end
class BillingAddress
attr_accessor :street, :city, :zipcode, :country, :state
end
class BillingAddressActiveModel
include ActiveModel::Model
attr_accessor :street, :city, :zipcode, :country, :state
end
Benchmark.ips do |x|
x.report("BillingAddressStruct") do
BillingAddressStruct.new(
'Street',
'City',
'Zipcode',
'Country',
'State'
)
end
x.report("BillingAddressStructFromHash:") do
BillingAddressStructFromHash.from_hash(
street: 'Street',
city: 'City',
zipcode: 'Zipcode',
country: 'Country',
state: 'State'
)
end
x.report("BillingAddressOpenStruct") do
BillingAddressOpenStruct.new(
street: 'Street',
city: 'City',
zipcode: 'Zipcode',
country: 'Country',
state: 'State'
)
end
x.report("BillingAddress") do
BillingAddress.new.tap do |billing_address|
billing_address.street = 'Street'
billing_address.city = 'City'
billing_address.zipcode = 'Zipcode'
billing_address.country = 'Country'
billing_address.state = 'State'
end
end
x.report("BillingAddressActiveModel") do
BillingAddressActiveModel.new(
street: 'Street',
city: 'City',
zipcode: 'Zipcode',
country: 'Country',
state: 'State'
)
end
x.compare!
end
@gwilczynski
Copy link
Author

Calculating -------------------------------------
BillingAddressStruct 1.504M (± 3.8%) i/s - 7.519M in 5.005860s
BillingAddressStructFromHash:
472.831k (± 2.5%) i/s - 2.365M in 5.006072s
BillingAddressOpenStruct
417.784k (± 4.9%) i/s - 2.118M in 5.082804s
BillingAddress 1.257M (± 2.6%) i/s - 6.291M in 5.007943s
BillingAddressActiveModel
124.096k (± 2.6%) i/s - 628.368k in 5.067165s

Comparison:
BillingAddressStruct: 1504236.7 i/s
BillingAddress: 1257026.5 i/s - 1.20x slower
BillingAddressStructFromHash:: 472830.7 i/s - 3.18x slower
BillingAddressOpenStruct: 417784.0 i/s - 3.60x slower
BillingAddressActiveModel: 124096.4 i/s - 12.12x slower

@tleish
Copy link

tleish commented Mar 11, 2017

A more compact version of the BillingAddressStructFromHash with same performance if interested

BillingAddressStructFromHash = Struct.new(:street, :city, :zipcode, :country, :state) do
  def self.from_hash(attributes)
    new(*attributes.values_at(*members))
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment