Should I port my application to .NET?
March 21, 2007 10:13 PM   Subscribe

Will managed code (.NET) work for me when I'm writing computationally intensive software?

I have this on again, off again project of writing my own ray tracer (a la POV ray: http://www.povray.org/) - just as a fun hobby. I have recently been learning C# and .NET, and am interested in taking advantage of the .NET framework for my GUI, file parser, etc.

My main concern is that porting everything to managed code will result in significantly slower performance for the heavy computational nature of the rendering engine. I'm not concerned about the difficulty in *rewriting* the code (it would be a learning exercise - which is the main point), but I want my code to run as fast as possible, and I'm skeptical that will happen with the overhead involved in managed code.

My question is therefore in 2 parts:
1) am I too skeptical of the CLR's performance? Will my code run just as fast as it does natively? I've seen conflicting reports on the web (some say its just as fast, some say otherwise). Any good side by side comparisons out there involving lots of floating point calculations?

2) if I want to port only my front end GUI, etc to .NET, and keep the back end in native C/C++, what is the best way to go about this? I have read about calling unmanaged DLLs from managed code or using C++/CLI with __nogc tags, etc, but I'm worried that these methods are either too clunky to efficiently pass data back and forth and/or involve a lot of overhead as the processor switches back and forth between managed and unmanaged code

Is there a standard manner of handling this issue? Is there a good paper/tutorial you could point me towards that addresses the questions I'm asking?

Thanks!
posted by jpdoane to Computers & Internet (8 answers total) 5 users marked this as a favorite
 
Well, it's inelegant but you could simply have the GUI call the actual program through an intermediate file. Everything I've read on the subject puts managed code in a pretty bad light for something like this. (I dabble with C# when I have time and the simplest things seem plodding to me when compared to C++.)
posted by IronLizard at 10:34 PM on March 21, 2007


I'm not sure that you'd find the VM really causing lots of performance problems. Remember that all your code is compiled to native code before it is run and I think that if you're running in a tight loop your first iteration may be slow while the JITer does its thing, but your next iterations should be fast.

I think you should do this just because you'd learn alot. If you think your code is slow you'd learn about how to profile .NET apps and work from there. If you really need the perf as you say you can always P/Invoke into unamanged code and do the nitty gritty down there.


As a side note, I remember running PovRay on my 486/33 and I don't think writing in managed code is going to push you back that far :-). A while back I saw a blog post where someone from Microsoft wrote a simple C++ app, profiled it and started to optimize it. Someone wrote the same app in C# and it ran faster off the bat than the C++ app.
posted by mge at 11:59 PM on March 21, 2007


1) It is hard to say without seeing your code, but .net is a managed environment and platform calls go through an intermediary layer which adds a few ops.

2) You can set it to link to your rendering engine as a native DLL. Pass parameters and the scene to the dll and get your image back. You can do this in an unsafe block in C#. There is a cost to marshaling but it seems like you could set things up to only pay it infrequently. I haven't extensively fooled with this side of .net in a year or so but it was definitely simpler to marshal values over objects. Things to google for are: platform invocation services (PINVOKE), marshaling, unsafe keyword.

IMO, .Net is really designed with developer productivity and maintainability in mind. This comes at the cost of a few things of which performance is one.
posted by rudyfink at 12:19 AM on March 22, 2007


Follow up:
If you do write in C#, I completely recommend working with graphics in unsafe blocks. The speed up on setting pixel values in an image by manipulating it in memory vs setpixel (or whatever it is called) is a stunning example.
posted by rudyfink at 12:22 AM on March 22, 2007


In lieu of a really, really long answer:

JIT compilation works really well, particularly since the structure of managed code allows the compiler to know more about what the code is doing than a C++ compiler can know. Unless you really know what you're doing, you will probably come out ahead with C#. Tests of the specific type of thing you're doing will give you the best idea, though. (For instance: crank through a hundred billion or a trillion random floating point calculations in C# and C++, see which one comes out faster, and by how much. Make sure you throw out the first run (after each recompile) on C# since it will include the once-only JITC.)

.NET is designed to call into legacy and native code easily, but I believe crossing the managed/unmanaged boundary is fairly expensive. This shouldn't be much of a problem if you're just feeding data from the GUI into the renderer and getting periodic status back, though. (pinvoke.net has a lot of examples of the simplest method--entering a translation from a C function declaration, then calling that directly.)

If you are using C++ templates to any good effect, porting to C# will be painful, since generics have a bunch of limitations, most of which show up as soon as you try to make something mathematical, such as a templatized matrix class.

C# is very easy, but using it all the time makes me think less clearly than I did while using C++ all the time. (I'm learning Haskell to try to counteract this.) (And some, but not all, of the other former C++ers around me have observed the same effect on themselves.)

My email's in my profile if you have any beginner-to-intermediate C# questions or any C++-to-C# transition questions.
posted by reventlov at 3:22 AM on March 22, 2007


Upon doing some rough benchmarks with some very arbitrary artificial floating-point twiddling code (all multiplication, division, test, and int-to-float conversion) this morning:

Microsoft C++, full speed optimization: 21 seconds
Microsoft C#, optimization turned on: 27 seconds
g++, -O3: 13 seconds

Interestingly, the end result number from the MS C++ compile is different from the results from the C# and g++ compiles. (The particular function I tested snowballs errors, and this is over the course of 1,000,000,000 iterations, so it's not too surprising.)
posted by reventlov at 11:43 AM on March 22, 2007


One of the larger problems with heavy computation work is that the runtime's memory management is geared towards the safe end, i.e., keep everything in memory until there's no chance of needing it.

It really all depends what the ultimate goal of the project is. If its to learn how to write a raytracer & maybe some simple textures & parsing, C# is definitely a better choice. The speed difference will likely be minimal for simple scenes, and you'll probably write it in 10x faster.

If you ever seriously want to develop this, at some point you'll be fighting C# more than liking it. C# is a wonderful language if you need to throw something up fast, but I think I'd shoot myself if I actually had to develop a large & complex application with it. Its elegance breaks down exponentially when you try to do something it wasn't originally intended for.

reventlov: I definitely feel your pain. Try OCaml sometime too. Its a good blend of functional parts for the algorithms and procedural/OO for the structure/etc. Input/networking/etc is also easier.
posted by devilsbrigade at 11:57 AM on March 22, 2007


The bigger thing than using managed code is using the correct algorithms. Also, during heavy loops, avoid creating objects and quickly destorying them. Reuse what you can, and when you can't, keep it to a minimum. Especially if this is for a learning experience, C# will be fine.
posted by cschneid at 9:14 PM on March 22, 2007


« Older 3-5-0-0   |   Husker Du? Newer »
This thread is closed to new comments.