Skip to content

Instantly share code, notes, and snippets.

@ms-ati
Created April 7, 2017 20:02
Show Gist options
  • Save ms-ati/3e62cca57ca32cd17ad2e2e2b14cc65e to your computer and use it in GitHub Desktop.
Save ms-ati/3e62cca57ca32cd17ad2e2e2b14cc65e to your computer and use it in GitHub Desktop.
Benchmark proposed optimization to `#eql?` method in Values gem
require "benchmark/ips" # gem install benchmark-ips
require "values"
fields = [:a, :b, :c, :d, :e, :f, :g]
# Current code
a = Value.new(*fields)
# Code with optimized `#eql?`
b = Value.new(*fields) do
def eql?(other)
self.equal?(other) || # same instance?
(
self.class == other.class &&
self.hash == other.hash &&
self.class::VALUE_ATTRS.all? do |field|
send(field) == other.send(field)
end
)
end
end
# Instances of current code
a1 = a.new("aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg")
a2 = a1
a3 = a.with(a1.to_h)
a4 = a1.with(g: "boo")
# Instance of modified code
b1 = b.new("aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg")
b2 = b1
b3 = b.with(b1.to_h)
b4 = b1.with(g: "boo")
raise "broken" unless
a1 == a2 &&
a1 == a3 &&
a1 != a4 &&
b1 == b2 &&
b1 == b3 &&
b1 != b4
Benchmark.ips do |x|
x.report("Same instance, current #eql?") { a1 == a2 }
x.report("Same instance, modified #eql?") { b1 == b2 }
x.report("Equal instance, current #eql?") { a1 == a3 }
x.report("Equal instance, modified #eql?") { b1 == b3 }
x.report("Different last field, current #eql?") { a1 == a4 }
x.report("Different last field, modified #eql?") { b1 == b4 }
end
# Calculating -------------------------------------
# Same instance, current #eql?
# 450.942k (± 2.5%) i/s - 2.263M in 5.022089s
# Same instance, modified #eql?
# 7.039M (± 3.7%) i/s - 35.404M in 5.037367s
# Equal instance, current #eql?
# 450.834k (± 2.2%) i/s - 2.266M in 5.028115s
# Equal instance, modified #eql?
# 637.966k (± 2.0%) i/s - 3.210M in 5.033335s
# Different last field, current #eql?
# 438.021k (± 2.7%) i/s - 2.203M in 5.033038s
# Different last field, modified #eql?
# 4.475M (± 3.5%) i/s - 22.409M in 5.013817s
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment