I was lying in bed last night and for some reason I remembered this issue that
was opened in July. I remembered, “Hey, I should add that to fast-elixir!” and
so today I did. I said that in general pattern matching is faster than guard
clauses, and one should prefer pattern matching to guard clauses if possible.
Turns out, I was pretty wrong. While using
length/1 in a guard clause is
indeed a less-than-optimal decision, there’s much more nuance to be discovered
The always helpful Michał Muskała took a peek at my example and raised some very valid concerns. I poked around further, benchmarked some other examples with Benchee, and boy was I surprised at the results!
So this is the first real surprise I found. Let’s look at the two following examples:
I’m not usually a betting man, but I would have put money on the pattern
matching version being at least a little faster than the one with
the guard clause. But I whipped up a benchmark, and it turns out that’s not the
case at all!
Semantically that’s the exact same code, but the pattern matching version is almost 30% slower. This is even more surprising given how common it is to pattern match on the first element of a tuple - I would have expected that to be a very highly optimized operation.
However, this trick is only good when it’s a single expression in the guard clause. In the following example, the guard clause version was almost 15% slower.
map_size/1 and tuple_size/1
length/1 is slow in guard clauses, then it makes sense that
tuple_size/1 should be slow too, right? WRONG! They’re actually super fast
in guard clauses! Let’s look at another example.
This time the runtimes were a little closer together, but still the guard clause was a little bit faster.
map_size/1 is similarly optimized as a guard clause and has similar results.
The lessons learned
Get creative with your benchmarks! Play around with different input sizes, different functions or applications of a certain concept you’re trying to benchmark. And don’t do what I did and jump to conclusions based on one or two examples.