Mark
8/25/2008 4:20:00 PM
Well, personally I think the appeal of case-insensativity is vastly
overblown, but it often comes up on serialization boundaries, messaging
systems, and configuration files. I've inherited a code base obsessed with
case-insensativity so I see the original pattern everywhere.
> - IMO this is a micro-optimization that really doesn't worth in most cases
> - if you had a real life huge loop a best practice would be to normalize the
> value outside of the loop not in each iteration (IMO you ran the ToLower in
> each ean every loop)
Yes, but time testing often means you replicate what the code does and wrap
a big loop around it. You can't optimize the loop invariants outside the
loop because that defeats the purpose of testing one pattern against the
other.
> IMO all this remains quite theoricall for now. I would much prefer a real
> life scenario...
>
> Also I'm not really sure to understand how it could help. If you tell C# to
> ignore case then behind the scene the code still has additional work to do
> something similar to what you have done explicitely...
The question is what "additional work" gets done. The String.ToLower() call
*guarantees* at least 1 full pass through the input and the possible creation
of a copy object which puts additional load on the garbage collection.
Depending on the app circumstances the extra object in the pool is 10x the
work.
Another way to replace the
switch (input.ToLower())
{...}
pattern is to use
if (input.Equals("1stcase", StringComparison.OrdinalIgnoreCase))
....
else if (input.Equal("2ndcase", StringComparison.OrdinalIgnoreCase))
....
etc.
Aside from the verbosity, with the 2nd pattern you don't make another copy
of the input and you keep all the advantages in comparison (length test,
object identity test). The only "additional work" in the 2nd pattern is one
character case test when you haven't matched.
But the 2nd pattern loses the flexibility of switch for optimization because
the ifs have to be executed in order.
Looking at some sample switch optimizations in ildasm, it seems that for
string operands with > 10 cases, the compiler builds a Dictionary<string,
int> jump vector in memory, so you get the benefit of hash table lookup
speeds.
If we had a comparitor option operand on switch, it could build a
new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
instead.
That way you get the switch optimization and case insensitivity without the
hit ToLower() brings.
Yes, you could consider this a micro optimization, but MS puts out other
whitepapers suggesting
if (str.Length == 0)
instead of
if (str == "")
and advising how many concatenations you should do before using StringBuilder.
Mark