Understanding User and Kernel Mode

Got the C# version running. Jesus H. Christ. Those are incredible results.

38064 ms kernel, 89326 ms user, 5000000 exceptions

That’s three times slower than even VC++ on WOW!

But wait, maybe .NET itself is just rotten slow? To test that I’ve added another loop with regular “if” branches taken in alternation, and an Exception object created for each branch so we have the same load on the garbage collector. And here’s the result:

15 ms kernel, 140 ms user, 2500000 + 2500000 branches

Branching without exceptions is EIGHT HUNDRED TIMES faster than executing a try-catch block! I tried shuffling the code around to see if the order of JIT compilation or the “warmup” phase made any difference, but they didn’t.

To be honest, I’m not sure where the kernel time is coming from in the second case – I thought the .NET GC was running in user mode. Anyway, I’ve cross-checked both test cases with the regular System.DateTime facility, and the sum of kernel + user mode is correct in each case.

You can download the C# 2.0 program here:
http://www.kynosarges.de/misc/throw_net.cs

I’ve compiled the program with csc /o throw_net.cs, meaning it runs in native 64-bit mode on my Vista 64 system.

And now I’ll have to go and rip out any and all exceptions I used to control program flow in my C# code, thinking they couldn’t be THAT slow. :frowning: