#include? vs #match
TL;DR: String#include? seems to be faster than String#match, which seems to be a result of not having to compile a regular expression. Adding an end-of-line anchor to the regexp implementation gives a slight performance improvement, but not enough to make it the optimal approach.
Today we were working on an implementation of #method_missing where we check to see if the called method was a predicate method, and if so, look for the existence of a corresponding attribute in a config object (an OpenStruct, in this case.) Probably more context that necessary but at any rate we wanted to know whether it was faster to use String#include? or String#match, so we came up with the following benchmark:
Based on these numbers, the choice to use #include? is quite obvious.
We decided to take a spin at refactoring the benchmark code (‘just for fun’, ‘because we can’, ‘why not?’).sample to see if we could alleviate some of the duplication.
Our first refactoring attempt was less than ideal; the way we used blocks seems to have skewed the result, making it look like the regexp implementation is equal or faster, but that result is inconsistent with the more explicit implementation, which I have more faith in.
Then we came up with this, which increased overall execution time, but kept the difference in implementation speeds relatively consistent, and so would probably serve well enough as a benchmarking harness for most simple cases where you want to determine how much performance one approach yields over another, without needing to know the exact execution time.
Finally, here is the implementation of #method_missing we landed on:
Hope this is useful and educational, and as always, that you are having fun and challenging yourself!
From → Ruby