The old implementation of String matchers worked by making a, potentially
lower-cased, copy of both the constructor arg, and the arg to `match` calls.
The new implementation does not make copies, and instead does per-character
lowering if needed. This is a win in **most** cases, with two exceptions:
1) Case-insensitive `Equals` between long strings. The old implementation
is easy to autovectorize by the compiler, which wins over the extra copy
with sufficiently long inputs.
2) Case-insensitive `ContainsSubstring` with inputs that trigger the worst
case complexity of O(m*n) of the naive implementation.
The latter is fixable with some elbow grease by implementing a proper
string search algorithm, but the former is a cost we have to live with.