Geeks With Blogs
.NET Corner Jeans, .NET and Physics (eka The Quantum Boy)
Its very tough to get into every possible part of modern software development process :- Debugging, Testing, Building, performance Optimization etc. Pardon me for skipping some sub-processes. But I was never hyper-aware about performance issues and It was always an afterthought of development process. But in the last couple of weeks I was continuously cracking my head in subtle issues related to performance optimization. For example when I am profiling a piece of test-case code for a database driver software I found following code:
for(int i=0; i < 750000; i++)
{
IDBCommand command = new XXXCommand();
command.CommandText = "Your [query/stored procedure] here";
//Some more code here...
}
The profiler showing a huge performance bottleneck at the piece of code where CommandText property is set. This seemed a bit strange to me. When I reverse engineered(I had no access to source code base tree till that) and found out following code at the set{} block of the property
public string CommandText
{
get
{
//...
}
set
{
//Code here...
if (string.Compare(this.m_commandText, value) != 0)
{
}
}
}
The profiler I'm using(AQTime4 : The best mixed mode profiler I have ever used although I didn't have chance to look into the Numega's DevPartner Studio) was very helpful in pointing out that the 90.1% of the time the method spends in exceuting the benign String.Compare method. Strange!!! "Alice in Perfmonland". A quick look at the .NET FCL's String::Compare method revealed what was going on.
public static int Compare(string strA, string strB)
{
return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, CompareOptions.None);
}
A navigation to the CompareInfo::Compare reveals a staggering information enough to solve the performance bottleneck. Its internally (For any method that CLR implements internally we have a MethodImplOptions.InternalCall flag with MethodImpl attribute) calling the unsafe function Compare. In all cases such 'internal' methods are implemented in native-C. Look into the 'Rotor' for good session of hacking the .NET InternalCall methods.
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern unsafe int Compare( void* pSortingTable, int win32LCID, string string1, string string2, CompareOptions options);

This function internally calls CompareString Win32 API
After discovering, I quickly prescribed that If you don't need some terrible Culture based UNICODE string comparison use != or == operator. Both the operator uses String::Equals which is 80% faster as far as my benchmark is concerned. To rise another step if you are comparing for empty string don't do :-

String.Compare(str1,String.Empty)

Do instead :-

str1.Length != 0

The last one is more faster although more subtle. This kind of optimizations are only visible if you have installed a pretty high loop(say 750000) into the test-code areas you suspect to have a performance bottleneck root. Performance Optimization is vast vast area and I just started taking a plunge into it. There are lot of topics to cover if somebody is interested and that goes down to IA-32 level Intel optimization techniques. For me the most interesting thing is that "How you can improve the performance of my .NET assembly by studying how JIT compiler generates fast IA-32 instructions and how could you optimize it even more by subtly changing the high-level code" Watch out for a mighty bite of "Performance Bug". Sooner or later you will be bitten. The more early it is , the more better you will be as a developer. See you soon.

-Thanks
Deb. Posted on Saturday, November 8, 2008 6:36 AM .NET Core | Back to top


Comments on this post: The Performance Bug

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © dbose | Powered by: GeeksWithBlogs.net