Skip to content

Instantly share code, notes, and snippets.

@amomchilov
Last active April 23, 2024 14:37
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 amomchilov/a2fec456210bc6db646f47a8ea5a6151 to your computer and use it in GitHub Desktop.
Save amomchilov/a2fec456210bc6db646f47a8ea5a6151 to your computer and use it in GitHub Desktop.
`case` statement vs `Hash` lookup
#!/usr/bin/ruby
# ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
# Comparison:
# Memo+Freeze+Ident H : 15333385.5 i/s
# Memo+Freeze Hash : 11604676.7 i/s - 1.32x slower
# case : 11026464.0 i/s - 1.39x slower
# Memo'ed Hash : 4516328.0 i/s - 3.40x slower
# Hash full of Ints : 4387124.4 i/s - 3.50x slower
require "awesome_print"
require "active_support/all"
require "sorbet-runtime"
require "benchmark/ips"
class MyEnum < T::Enum
enums { A = new; B = new; C = new }
end
def lookup_case(e)
case e
when MyEnum::A then 1
when MyEnum::B then 2
when MyEnum::C then 3
end
end
def lookup_hash_full_of_ints(e)
{
MyEnum::A => 1,
MyEnum::B => 2,
MyEnum::C => 3,
}[e]
end
MEMOED_HASH = {
MyEnum::A => 1,
MyEnum::B => 2,
MyEnum::C => 3,
}
def lookup_memoed_hash_full_of_ints(e)
MEMOED_HASH[e]
end
MEMOED_FROZEN_HASH = {
MyEnum::A => 1,
MyEnum::B => 2,
MyEnum::C => 3,
}.freeze
def lookup_memoed_frozen_hash_full_of_ints(e)
MEMOED_HASH[e]
end
MEMOED_FROZEN_IDENT_HASH = {
MyEnum::A => 1,
MyEnum::B => 2,
MyEnum::C => 3,
}.compare_by_identity.freeze
def lookup_memoed_frozen_identity_hash_full_of_ints(e)
MEMOED_FROZEN_IDENT_HASH[e]
end
a = (MyEnum.values * 100).shuffle
width = 20
Benchmark.ips do |x|
x.config(warmup: 1, time: 5)
x.report("case".ljust(width, " ")) do |times|
i = 0
while (i += 1) <= times
lookup_case a[i % a.size]
end
end
x.report("Hash full of Ints".ljust(width, " ")) do |times|
i = 0
while (i += 1) <= times
lookup_hash_full_of_ints a[i % a.size]
end
end
x.report("Memo'ed Hash".ljust(width, " ")) do |times|
i = 0
while (i += 1) <= times
lookup_hash_full_of_ints a[i % a.size]
end
end
x.report("Memo+Freeze Hash".ljust(width, " ")) do |times|
i = 0
while (i += 1) <= times
lookup_memoed_frozen_hash_full_of_ints a[i % a.size]
end
end
x.report("Memo+Freeze+Ident H".ljust(width, " ")) do |times|
i = 0
while (i += 1) <= times
lookup_memoed_frozen_identity_hash_full_of_ints a[i % a.size]
end
end
x.compare!
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment