Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@casperisfine
Created July 8, 2020 07:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save casperisfine/fdd6d2790cf5c580856a8595d1d301da to your computer and use it in GitHub Desktop.
Save casperisfine/fdd6d2790cf5c580856a8595d1d301da to your computer and use it in GitHub Desktop.
$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
$ ruby /tmp/struct.rb
Warming up --------------------------------------
hash 1.450M i/100ms
naive 8.267k i/100ms
lazy-cached 68.069k i/100ms
explicit 415.985k i/100ms
Calculating -------------------------------------
hash 14.223M (± 3.4%) i/s - 71.047M in 5.001074s
naive 84.675k (± 3.0%) i/s - 429.884k in 5.081532s
lazy-cached 683.427k (± 1.8%) i/s - 3.472M in 5.081364s
explicit 4.212M (± 2.5%) i/s - 21.215M in 5.040363s
Comparison:
hash: 14222972.0 i/s
explicit: 4211882.2 i/s - 3.38x (± 0.00) slower
lazy-cached: 683426.7 i/s - 20.81x (± 0.00) slower
naive: 84674.5 i/s - 167.97x (± 0.00) slower
require 'objspace'
def NaiveStruct(**kwargs)
Struct.new(*kwargs.keys).new(*kwargs.values)
end
ExplicitStruct = Struct.new(:foo, :bar)
def print_size(label, *elements)
puts "#{label}: #{elements.map { |e| ObjectSpace.memsize_of(e) }.sum}B"
end
print_size("hash", {foo: 1, bar: 2})
print_size("explicit", ExplicitStruct.new(foo: 1, bar: 2))
print_size("naive", NaiveStruct(foo: 1, bar: 2), NaiveStruct(foo: 1, bar: 2).class)
hash: 168B
explicit: 40B
naive: 632B
require 'benchmark/ips'
def NaiveStruct(**kwargs)
Struct.new(*kwargs.keys).new(*kwargs.values)
end
STRUCT_CACHE = {}
def LazyCached(**kwargs)
keys = kwargs.keys.sort
klass = (STRUCT_CACHE[keys] ||= Struct.new(*keys, keyword_init: true))
klass.new(**kwargs)
end
ExplicitStruct = Struct.new(:foo, :bar)
Benchmark.ips do |x|
x.report('hash') { {foo: 1, bar: 2} }
x.report('naive') { NaiveStruct(foo: 1, bar: 2) }
x.report('lazy-cached') { LazyCached(foo: 1, bar: 2) }
x.report('explicit') { ExplicitStruct.new(foo: 1, bar: 2) }
x.compare!
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment