I’m using Rails 3.2.3 with Ruby 1.9.3p0.
I’m finding that I often have to determine whether a string occurs in a list of options. It seems I can use the Ruby array .include method:
<% if ['todo','pending','history'].include?(params[:category]) %>
or the regular expression equals-tilde match shorthand with vertical bars separating options:
<% if params[:category] =~ /todo|pending|history/ %>
Is one better than the other in terms of performance?
Is there an even better approach?
Summary:
Array#include?withStringelements wins for both accepted and rejected inputs, for your example with only three acceptable values. For a larger set to check, it looks likeSet#include?withStringelements might win.How to Test
We should test this is empirically.
Here are a couple of alternatives that you may want to consider as well: pre-compiled regex, a list of symbols, and a
SetwithStringelements.I would imagine that the performance may also depend on whether most of your inputs fall into the expected set, and are accepted, or whether most are outside the set, and are rejected.
Here’s an empirical test script:
Results
Conclusions
(see the Summary above)
It makes sense to me, upon reflection, that the Array of Symbols would be very slow for rejected inputs, because every single one of those random strings must be interned in the Symbol table before the check can be made.
It makes less sense to me, even after pondering, that the compiled Regexp would perform so badly, especially compared to the Regexp interpreted as a literal in the code. Can anyone explain why it does so badly?