Which would be faster in looking up a String against a known group, a Hash(String=>Bool) or a case
?
input = %w(a b c x y z)
valid = { "a" => true, "z" => true }
input.find { |x|
!valid.has_key?(x)
# or
case x
when "a", "z"
false
else
true
end
}
For a small amount of relatively small comparison values known at compile time, it is certainly the fastest and (as Faustino pointed out) most memory-efficient to employ direct comparisons.
The case
and NamedTuple
examples essentially boil down to a series of x == "a" || x == "z"
. This is as simple as it gets, meaning a very low code complexity, no heap allocations, fast comparison.
When using a hash, each comparison invokes the hashing algorithm (hence the name) which adds quite a bit of overhead. Hashes are however a great data structure for storing complex values or dynamic values not known at compile time.
When comparing larger collections of strings, at some point the simplistic approach is not that efficient anymore because it needs to compare each and every item in full length. A more efficient approach are specialized data structures for this kind of lookup known as prefix tree (see https://github.com/luislavena/radix for a Crystal implementation).