Skip to content

Instantly share code, notes, and snippets.

@emilebosch
Created May 21, 2023 18:00
Show Gist options
  • Save emilebosch/b6a29f48d61c4aad01c034b353141555 to your computer and use it in GitHub Desktop.
Save emilebosch/b6a29f48d61c4aad01c034b353141555 to your computer and use it in GitHub Desktop.
ofstruct (master) ∆ ruby benchmark/hash_ofstruct_ostruct.rb
Warming up --------------------------------------
Hash 679.719k i/100ms
Custom 514.475k i/100ms
DefineMethod 468.338k i/100ms
Eval 514.546k i/100ms
MethodMissing 402.570k i/100ms
HashMissing 324.535k i/100ms
OpenFastStruct 92.942k i/100ms
Struct 357.038k i/100ms
OpenStruct 17.461k i/100ms
Calculating -------------------------------------
Hash 6.955M (± 0.2%) i/s - 35.345M in 5.081933s
Custom 5.202M (± 0.1%) i/s - 26.238M in 5.043721s
DefineMethod 4.734M (± 0.2%) i/s - 23.885M in 5.045175s
Eval 5.204M (± 0.1%) i/s - 26.242M in 5.042651s
MethodMissing 4.081M (± 0.1%) i/s - 20.531M in 5.031099s
HashMissing 3.289M (± 0.4%) i/s - 16.551M in 5.032879s
OpenFastStruct 940.320k (± 0.3%) i/s - 4.740M in 5.040936s
Struct 3.609M (± 0.1%) i/s - 18.209M in 5.045569s
OpenStruct 174.827k (± 1.1%) i/s - 890.511k in 5.094294s
Comparison:
Hash: 6955125.0 i/s
Eval: 5203980.1 i/s - 1.34x (± 0.00) slower
Custom: 5202162.6 i/s - 1.34x (± 0.00) slower
DefineMethod: 4734297.9 i/s - 1.47x (± 0.00) slower
MethodMissing: 4080834.9 i/s - 1.70x (± 0.00) slower
Struct: 3608902.5 i/s - 1.93x (± 0.00) slower
HashMissing: 3288681.2 i/s - 2.11x (± 0.00) slower
OpenFastStruct: 940319.7 i/s - 7.40x (± 0.00) slower
OpenStruct: 174827.0 i/s - 39.78x (± 0.00) slower
# frozen_string_literal: true
require "benchmark/ips"
require "ostruct"
require_relative "../lib/ofstruct"
class HashMissing < Hash
def initialize(hash = {})
super().merge!(hash)
end
def method_missing(x, *args)
self[x]
end
end
class DefineMethod
def initialize(x)
@x = x
end
def method_missing(x, *args)
self.class.define_method(x) do
@x[x]
end
@x[x]
end
end
class Eval
def initialize(x)
@x = x
end
def method_missing(x, *args)
a = "def #{x}; @x[:#{x}]; end"
self.class.class_eval(a)
@x[x]
end
end
class MethodMissing
def initialize(x)
@x = x
end
def method_missing(x, *args)
@x[x]
end
end
#x = Eval.new({name:"ok"})
# p x.name
# p x.name
# exit
class Wtf
def initialize(x)
@x = x
end
def name
@x[:name]
end
end
# x = O.new({name:"ok"})
# p x.name
# exit
X = Struct.new(:name, :surname, keyword_init: true)
Benchmark.ips do |x|
x.report "Hash" do
object = { name: "John" }
object[:name]
object[:surname] = "Smith"
object[:surname]
end
x.report "Custom" do
object = Wtf.new({ name: "John" })
object.name
end
x.report "DefineMethod" do
object = DefineMethod.new({ name: "John" })
object.name
end
x.report "Eval" do
object = Eval.new({ name: "John" })
object.name
end
x.report "MethodMissing" do
object = MethodMissing.new({ name: "John" })
object.name
end
x.report "HashMissing" do
object = HashMissing.new({ name: "John" })
object.name
end
x.report "OpenFastStruct" do
object = OpenFastStruct.new(name: "John")
object.name
object.surname = "Smith"
object.surname
end
x.report "Struct" do
object = X.new(name: "John")
object.name
object.surname = "Smith"
object.surname
end
x.report "OpenStruct" do
object = OpenStruct.new(name: "John")
object.name
object.surname = "Smith"
object.surname
end
x.compare!
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment