Last active
June 13, 2024 04:31
-
-
Save jgaskins/5dd9b3557e6f86586d605792af15e585 to your computer and use it in GitHub Desktop.
Benchmark pattern matching in Crystal using Arrays and Tuples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
➜ 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] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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