Did you know how evil string.ToLower() can sometimes be?
Let me explain...
Very often I see code similar to this:
void DoBadAction (string val)
{
if (val.ToLower() == "someValue")
{ //do something
}
}
The code above can lead up to 4 times in performance loss when doing string comparison operations.
Best method to do such kind of case insensitive comparison is using string.Equals(...) method.
void DoGoodAction(string val)
{
if (val.Equals("someValue", StringComparison.OrdinalIgnoreCase))
{ //do something
}
}
Why is it so? The reason lies in the string type peculiarity - it is immutable.
Since it is an immutable - string.ToLower() will always return new string instance. Thus generating extra instance of string on every ToLower() call.
Detailed information about string.Equals with StringComparison enumeration can be found here.
Other performance related tips and tricks can be found here.
Friday, February 01, 2008
When string.ToLower() is Evil
Опубліковано V о 2/01/2008 12:05:00 AM
Мітки: .NET, performance, tips'n'tricks
Subscribe to:
Post Comments (Atom)
Since you're talking performance, how about showing some stats. When will the performance gain matter ? ..... etc ..
ReplyDeleteSince you're stating a 4 times improvement , you should also provide some code.
Sounds like a good excuse for an Extension Method in C# 3.0:
ReplyDeletesomeString.EqualsIgnoreCase("somevalue")
if (val.ToLower() == "someValue")
ReplyDelete{ //this code will never be reached
}
you've got a slightly bigger problem then performance, in that your if statement will never return true
ReplyDeleteThanks for the tip. I've been using .tolower() for a long time now.
ReplyDeleteif (val.ToLower() == "someValue")
ReplyDelete{ //this code will never be reached
}
That code was somewhat ironical.
Nor it was a sample of bad comparison, but also source of potential bugs.
Here are the timings received when doing comparison:
ReplyDeleteTime with .ToLower(): 00:00:00.5100357, With .Equals: 00:00:00.1893425. N times: 2,69
Time with .ToLower(): 00:00:00.5379754, With .Equals: 00:00:00.1816390. N times: 2,96
Time with .ToLower(): 00:00:00.4981258, With .Equals: 00:00:00.1801120. N times: 2,77
Time with .ToLower(): 00:00:00.5016140, With .Equals: 00:00:00.1814274. N times: 2,76
Time with .ToLower(): 00:00:00.5302074, With .Equals: 00:00:00.1734722. N times: 3,06
Time with .ToLower(): 00:00:00.5109213, With .Equals: 00:00:00.1852686. N times: 2,76
Time with .ToLower(): 00:00:00.5015992, With .Equals: 00:00:00.1766858. N times: 2,84
Time with .ToLower(): 00:00:00.5228205, With .Equals: 00:00:00.1793420. N times: 2,92
Time with .ToLower(): 00:00:00.5160138, With .Equals: 00:00:00.1861520. N times: 2,77
Time with .ToLower(): 00:00:00.5028534, With .Equals: 00:00:00.1801821. N times: 2,79
Time with .ToLower(): 00:00:00.5099061, With .Equals: 00:00:00.1817483. N times: 2,81
Time with .ToLower(): 00:00:00.5155395, With .Equals: 00:00:00.1851748. N times: 2,78
Time with .ToLower(): 00:00:00.4984701, With .Equals: 00:00:00.1841835. N times: 2,71
Time with .ToLower(): 00:00:00.5664112, With .Equals: 00:00:00.1917371. N times: 2,95
Time with .ToLower(): 00:00:00.5351288, With .Equals: 00:00:00.1791308. N times: 2,99
Time with .ToLower(): 00:00:00.5135746, With .Equals: 00:00:00.1900286. N times: 2,70
Time with .ToLower(): 00:00:00.5044958, With .Equals: 00:00:00.1747117. N times: 2,89
Time with .ToLower(): 00:00:00.5240497, With .Equals: 00:00:00.1732485. N times: 3,02
Time with .ToLower(): 00:00:00.5106127, With .Equals: 00:00:00.1876307. N times: 2,72
Time with .ToLower(): 00:00:00.4953805, With .Equals: 00:00:00.1818622. N times: 2,72
Thanks to Vadym for the stats. I suppose it's kinda clear from the performance side, Equals is better. And it's neat too =)
ReplyDeleteAlas, we're still left with ToLower() or ToUpper() when using CompareTo() :(
ReplyDeleteI prefer Sring.Compare()
ReplyDeleteEx:
String.Compare (string strA, string strB, bool ignoreCase);
This Post will definately explain you how you can overcome the problem of comparision
ReplyDeletehttp://dotnetguts.blogspot.com/2007/07/improving-performance-of-net.html
Good article.
ReplyDeleteStringBuilder is not always necessary, see this artcile http://www.yoda.arachsys.com/csharp/stringbuilder.html
lifescience neighbors bound restrained researchers paragraphs nasdaq friesen keydocuments least tourist
ReplyDeletelolikneri havaqatsu
It was very nice blog, thanks for shearing this idea.
ReplyDeleteFantastic Demo
ReplyDelete