Skip to content

Instantly share code, notes, and snippets.

@flash-gordon
Created August 11, 2016 22:46
Show Gist options
  • Save flash-gordon/f9b99f8c28f0a0d65902cae18035a45f to your computer and use it in GitHub Desktop.
Save flash-gordon/f9b99f8c28f0a0d65902cae18035a45f to your computer and use it in GitHub Desktop.
Bundler.setup(:default, :benchmarks)
Bundler.require
require 'benchmark'
require 'benchmark/ips'
ATTRS = ('a'..'z').to_a.map(&:to_sym).take(10)
class ManualStruct
class_eval(<<-RUBY)
def initialize(values)
assert_known_attributes(values)
#{ATTRS.map { |a| "@#{a}" }.join(', ')} = #{ATTRS.map { |a| "values[:#{a}]" }.join(', ')}
end
RUBY
def assert_known_attributes(values)
actual = values.keys
unknown, missing = actual - ATTRS, ATTRS - actual
fail if unknown.any? || missing.any?
end
end
class ManualStructWithoutAssertion
class_eval(<<-RUBY)
def initialize(values)
#{ATTRS.map { |a| "@#{a}" }.join(', ')} = #{ATTRS.map { |a| "values[:#{a}]" }.join(', ')}
end
RUBY
end
class KeywordStruct
class_eval(<<-RUBY)
def initialize(#{ATTRS.map { |a| "#{a}: " }.join(', ')})
#{ATTRS.map { |a| "@#{a}" }.join(', ')} = #{ATTRS.join(', ')}
end
RUBY
end
values = Hash[*ATTRS.zip(ATTRS).flatten(1)]
Benchmark.ips do |x|
x.report('manual') { ManualStruct.new(values) }
x.report('manual without assert') { ManualStructWithoutAssertion.new(values) }
x.report('keyword') { KeywordStruct.new(values) }
x.compare!
end
__END__
Warming up --------------------------------------
manual 14.345k i/100ms
manual without assert
50.236k i/100ms
keyword 19.769k i/100ms
Calculating -------------------------------------
manual 133.857k (± 8.2%) i/s - 674.215k in 5.073288s
manual without assert
643.960k (± 8.7%) i/s - 3.215M in 5.039824s
keyword 187.779k (±13.2%) i/s - 929.143k in 5.048746s
Comparison:
manual without assert: 643959.9 i/s
keyword: 187779.0 i/s - 3.43x slower
manual: 133856.8 i/s - 4.81x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment