We traced a performance bottleneck to a single function recently. Interestingly enough, this function has been in existence (running in a production environment in all of its glory) for roughly 4 years now. Only now that we are required to execute the offending piece of code approximately 10 million times within a short four hour window has the problem actually surfaced.Our function has about 100 LOC. It contains custom collection class references, string manipulation, financial calculations and numerous other operations which I would flag as suspicious. We successfully avoided performance counters and simply stepped through the code after ensuring we had set an adequate number of timespan variables to track execution times the old fashion way. As it works out, DateTime.Parse we the bottleneck and our simple logic to determine is IsDate() or IsDatePast() might as well have been the most complicated, resource-eating routines on the planet.Why was this? Well, the Parse method tries very hard to make sense of the string that’s passed to it in order to create a valid DateTime value. It ignores leading and trailing white space, and unrecognized characters if possible, and it fills in missing information with the corresponding current date and time values. Parse will throw a FormatException if it’s unable to decipher the string you send to it, but otherwise, it bends over backwards for you. Our guess is it tries to do too much for its own good and exhausts itself in the process.We tried to replace the Parse method with the other DateTime static method — ParseExact — but it didn’t provide much relief.In the end, we got creative. We opted to create a simple function which first instantiates a new DateTime reference by using the month, day and year from the string representation of the date. (We were lucky because we knew this string would either be in the MM/DD/YYYY format or emtpy.) Would you believe that splitting our string and then constructing a new DateTime reference performed considerably better than using the standard DateTime.Parse method? Well, it did.
October 25th, 2006 at 7:55 pm
I found a bottleneck in some work code which turned out to be DateTime.Parse as well.
I used the dotTrace profiler (pre-release 2.0) to find the bottleneck:
http://www.jetbrains.com/profiler/features/
which showed how much time was being spent in that function.
To peak into the function itself to see what’s going on, there’s always Reflector:
http://www.aisto.com/roeder/dotnet/
If you dig into the implementation, there’s an internal method “DateTimeParse.Lex” that’s doing very complicated token parsing (which in turn calls other lexing methods internally.)
Basically, a big mess if you know you’re going to get the date in specific format.
October 25th, 2006 at 11:55 pm
The fact that your solution works faster is probably caused by the fact that you know the format of the date and DateTime.Parse does not - i.e.: it probably takes into consideration local settings, the thread culture etc, while you know exactly what is the date format.
Other than that - a nice find! Thanks
October 26th, 2006 at 12:17 am
Hi Johnny,
I’m very sorry to be off topic here but I’d like to ask if you use any plugin to display the code in wordpress because it’s looking great. Couldn’t find any contact form, I would be pleased if you answer me - if you want via e-mail and delete this comment.
Cheers
Andy
October 26th, 2006 at 2:18 am
Have you tried using DateTime.TryParse?
It’s new in .net 2.0 and it’s so much faster than Datetime.Parse
October 26th, 2006 at 3:23 am
You could also try using a Regular Expression to make sure the data isn’t total rubbish, then move on to the TryParse()
October 26th, 2006 at 8:26 am
We’d hadn’t tried it out but it’s worth a shot. Thanks for the suggestion.
October 26th, 2006 at 8:28 am
Adam, thanks for drilling into the details. I appreciate the feedback. (And sorry your comment didn’t post immediately. Since you included more than one link it was held for moderation temporarily. I’m going to have to work on this because if you are anything like me you like instant gratification and would like to see your comments immediately.) Thanks again.
October 26th, 2006 at 8:32 am
No worries, Andy. I’m using plenty of plugins, but I’m not sure they contribute to the overall look of the site. I’ll put an article together outlining the details later today. Thanks for the interest.