A
Anonymous
Guest
Hello All, I'm new to this forum, but a C# engineer. Love the MP product, and was excited to see you guys really blazed ahead and used C# for the implementation. I read some postings about improving performance, and just wanted to shoot you some things.
My company is EXTREMELY concerned with performance. Every possible IL instruction that can be reduced, every nanosecond gained, is a win in their opinion. With that said, I did a series of benchmarking tests on various common uses of C#, and some other general suggestions to possibly improve performance with Beta2. So, here are some obvious things to change/fix if you so desire to improve performance: (Note: I benchmarked all these situations with the NT high performance monitor calls through C#)
1) Stay away from foreach loops, the performance is horrible. Especially when walking through System.Collection classes. The absolute fastest way to walk anything is with a for loop, but not just any for loop. You must take the end loop check out of the for statement. So, for instance:
for (int i=0; i < myArray.Count; i++) // Slower way
int nSize = myArray.Count;
for (int i=0; i < nSize; i++) // Faster way
Although there is an MSDN article stating that the release optimizer takes benefit in using the myArray.Count in the 'for' to remove the boundry check in the 'for' block code, it's still slower. Maybe .NET 2.0 will fix this. Of course, doing a calcuation in the for is even worse, like this:
for (int i=0; i < nSize/2; i++)
This division is evaluated every time, which is of course bad. So, point #1, remove all foreach statements and take the loop checks out of the for statement.
2) Next, an obvious one which you may already do. Implement a dispose pattern for all your objects, and dispose them just like you would in C++. The GC lets you get lazy, but at the expense of it taking cycles from you during the GC cleanup. Treat your new'd classes like C++, you never know when the GC will decide it needs to execute.
3) If/else statements are far faster than switch statements, even at 10 conditions, even with pumping the last 'if' check millions of times. You can at least order the if statements based on which ones you think will be checked more than others. C# organizes a case statement to optimal searching, so it rearranges things on you potentially. switch looks nice, but it's slower.
4) If you do a 'new' on a class, don't bother checking for NULL, since 'new' throws an exception. You'll never get control in your code after a 'new' and have the reference be NULL. It's just wasted 'if' checks.
5) Try to prevent object creation as rule of thumb. Don't 'new' objects in the declaration or constructor if they can be done later. They may never be needed, so their declaration could potentially be skipped.
6) Prefer 'as' object casting to the C style casting. It's simply faster.
7) Methods are inlined if they are under 32 bytes of IL, so keep those properties small if possible. You can roughly do about 3 lines of code in the property and keep it under 32 bytes of IL.
8 ) Remove numberic type conversions if possible, they are very expensive.
9) Learn about C# boxing, and how it's a performance killer. Granted, Boxing is the real killer, unboxing is far less expensive. Try to prevent any boxing in performance critical areas.
Ok, that's it for now. Hopefully this information is of some use. Keep up the great work you guys.
My company is EXTREMELY concerned with performance. Every possible IL instruction that can be reduced, every nanosecond gained, is a win in their opinion. With that said, I did a series of benchmarking tests on various common uses of C#, and some other general suggestions to possibly improve performance with Beta2. So, here are some obvious things to change/fix if you so desire to improve performance: (Note: I benchmarked all these situations with the NT high performance monitor calls through C#)
1) Stay away from foreach loops, the performance is horrible. Especially when walking through System.Collection classes. The absolute fastest way to walk anything is with a for loop, but not just any for loop. You must take the end loop check out of the for statement. So, for instance:
for (int i=0; i < myArray.Count; i++) // Slower way
int nSize = myArray.Count;
for (int i=0; i < nSize; i++) // Faster way
Although there is an MSDN article stating that the release optimizer takes benefit in using the myArray.Count in the 'for' to remove the boundry check in the 'for' block code, it's still slower. Maybe .NET 2.0 will fix this. Of course, doing a calcuation in the for is even worse, like this:
for (int i=0; i < nSize/2; i++)
This division is evaluated every time, which is of course bad. So, point #1, remove all foreach statements and take the loop checks out of the for statement.
2) Next, an obvious one which you may already do. Implement a dispose pattern for all your objects, and dispose them just like you would in C++. The GC lets you get lazy, but at the expense of it taking cycles from you during the GC cleanup. Treat your new'd classes like C++, you never know when the GC will decide it needs to execute.
3) If/else statements are far faster than switch statements, even at 10 conditions, even with pumping the last 'if' check millions of times. You can at least order the if statements based on which ones you think will be checked more than others. C# organizes a case statement to optimal searching, so it rearranges things on you potentially. switch looks nice, but it's slower.
4) If you do a 'new' on a class, don't bother checking for NULL, since 'new' throws an exception. You'll never get control in your code after a 'new' and have the reference be NULL. It's just wasted 'if' checks.
5) Try to prevent object creation as rule of thumb. Don't 'new' objects in the declaration or constructor if they can be done later. They may never be needed, so their declaration could potentially be skipped.
6) Prefer 'as' object casting to the C style casting. It's simply faster.
7) Methods are inlined if they are under 32 bytes of IL, so keep those properties small if possible. You can roughly do about 3 lines of code in the property and keep it under 32 bytes of IL.
8 ) Remove numberic type conversions if possible, they are very expensive.
9) Learn about C# boxing, and how it's a performance killer. Granted, Boxing is the real killer, unboxing is far less expensive. Try to prevent any boxing in performance critical areas.
Ok, that's it for now. Hopefully this information is of some use. Keep up the great work you guys.