Monday, December 18, 2006

VB.NET vs. C#: An example of the difficulty of micro-optimization

Is VB.NET slower than C#? Shawn Weisfeld wrote a little rant of frustration on the difference in speed between C# and VB.NET.  Personally, I don't use VB.NET, as I dislike it's slightly more verbose syntax and the fact that it has compiler options that might break your code, which makes copy-pasting more complex.  I like to be able to read code and not have to worry to much about yet another setting ;-).  Of course habit is a biggy - and I came from C++ and Java so naturally C# seems easier to learn, even if the difference is mostly just minor aesthetic details.

The micro-benchmark he used was essentially a number of integer calculations in a for loop.  C# is roughly 3 times as fast, even though both programs decompile to (almost) the same C# code.  The result of that calculation is printed, so the compiler can't just throw away the entire loop in a benchmark-defeating bout of optimization.  Here's his C# code:

for (long num7 = 0; num7 < 0x5f5e100; num7++) {
num5 = (num2 + (num3 * num4)) + num5;
num6 = ((((num4 * num3) * 12) + num2) + (num2 + (num3 * num4))) + num6;
}

All variables are initialized to zero, and are 64-bit signed integers.  His post contains the full compilable code.  I've never tried VB.NET yet, but heck, virtually the same program, and this weird difference?  I copied his code, fired up C# and then VB.NET for the first time, and lo and behold: C# needs 3 seconds and VB.NET 9.


So my first thought is "Darn, my machine is slower than his" :-). Then: There are a number of odd things about his benchmark...



  • variables are initialized to zero, and remain zero - might the compiler be smarter than we think and have figured that out?

  • Using 64-bit integers is uncommon, and they are slower (even on 64-bit machines)

  • I'm running this from inside Visual Studio by pressing play - which despite "release" mode still connects a debugger which impacts certain types of code heavily.

Running without Visual Studio bears no improvement.  Changing the initial conditions makes no difference.  Changing to 32-bit integers  speeds things up by a factor 2 - but doesn't change VB's relative slowness.  Funnily enough, running in 32-bit more and outside of Visual Studio speeds things up a further factor 2, but it still doesn't solve our paradox, especially as C# speeds up much more now!  32-bit C# outside of visual studio takes a mere 150ms as opposed to 3000ms using 64-bit integers inside visual studio.


Finally the key: while playing around, VB ended up throwing an integer overflow exception, where C# didn't!  VB.NET is checking integer overflow and that is costly.  Disabling overflow checking lets VB.NET run just as quickly as C#.


I think an improvement from 9000ms to 150ms ain't bad at all.  What do you think?

1 Comments:

At 21 December, 2006 16:16 , Anonymous Shawn Weisfeld said...

Eamon I think you hit the nail on the head. Checking the 'Remove Integer Overflow Checks' options under Properties | Compile | Advanced Compile Options allowed my VB Code to consistently perform the test in under 3 seconds. Good Catch.

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home