Skip to content

Instantly share code, notes, and snippets.

@jgaskins
Last active June 13, 2024 04:31
Show Gist options
  • Save jgaskins/5dd9b3557e6f86586d605792af15e585 to your computer and use it in GitHub Desktop.
Save jgaskins/5dd9b3557e6f86586d605792af15e585 to your computer and use it in GitHub Desktop.
Benchmark pattern matching in Crystal using Arrays and Tuples
➜ Code crystal run --release bench_tuple_vs_array_for_pattern_matching.cr
true
array 27.17k ( 36.80µs) (± 1.58%) 156kB/op 96.02× slower
tuple 2.61M (383.32ns) (± 0.85%) 0.0B/op fastest
[true]
require "benchmark"
record Foo
record Bar
# Quick function check
pp [Foo, Bar] === [Foo.new, Bar.new]
# Define a mutable object to store the result into so LLVM doesn't
# optimize out the Tuple version entirely.
result = [false] of Bool
Benchmark.ips do |x|
n = 1_000
x.report "array" do
n.times do
result[0] = case [Foo.new, Bar.new]
when [Foo, Bar]
true
else
false
end
end
end
x.report "tuple" do
n.times do
result[0] = case {Foo.new, Bar.new}
when {Foo, Bar}
true
else
false
end
end
end
end
# Ensure we run a side effect on the result — again, so LLVM doesn't
# optimize out the Tuple version.
pp result
class Array
# The stdlib does not define `Array#===`, so we define it for this benchmark
def ===(other : Array) : Bool
return false if size != other.size
size.times do |index|
unless self[index] === other[index]
return false
end
end
true
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment