Skip to main content
GameDev.net gamedev.net
🔒 Locked

C# vs. C++

Started by EmrldDrgn Jul 26, 2006 at 2:27 AM 45 replies 6.6k views
Original Post
EmrldDrgn
EmrldDrgn
I much prefer C# to C++, but I've heard that its automatic garbage collection makes it ridiculously slow compared to C++. How much slower would that make it, and would it be insignificant on modern computers, as long as my programs don't get TOO ridiculously large?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~I program in C++, on MSVC++ '05 Express, and on Windows. Most of my programs are also for windows.
Promit
Promit
Quote:
Original post by EmrldDrgn
I much prefer C# to C++, but I've heard that its automatic garbage collection makes it ridiculously slow compared to C++.
You heard wrong.
Quote:
How much slower would that make it, and would it be insignificant on modern computers, as long as my programs don't get TOO ridiculously large?
It's completely insignificant, and unless you're a fairly skilled C++ coder, it's not unthinkable that C# will actually be faster. And when I say "skilled", we're talking, write your own custom memory manager which handles multiple heaps, prevents fragmentation, etc. Hard core memory work. Writing performance C++ is non-trivial.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
ToohrVyk
ToohrVyk
A programming language has no "speed". However, the average program of an average programmer written in C# would be about as slow as a program written in C++. However, it would not cause memory leaks and segmentation faults (although it might leak file handles or GDI resources).

In the end, how fast your program runs depends solely on your skill and your use of a profiler.
Enselic
Enselic
Quote:
Original post by EmrldDrgn
How much slower would that make it?

That's impossible to answer because we don't know how well you will write the code, or what you will code.

From my own experience with C#, I've had no problem with its performance.
Ryan_001
Ryan_001
The word 'performance' is quite a loaded term and covers a large range of different metrics. Hence ur likely to get very biased opinions unless ur extremely specific about what aspect of performance ur interested in, and the circumstances surounding it.

That said, I prefer C++ as it allows me to easily delve into assembly for those times when performace is crucial, and still maintain all the bells and whistles of a higher level language, even if it is at the cost of some sytactical discrepencies.
Promit
Promit
Quote:
Original post by Ryan_001
That said, I prefer C++ as it allows me to easily delve into assembly for those times when performace is crucial
How very amusing.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Ryan_001
Ryan_001
Quote:
Original post by Promit
Quote:
Original post by Ryan_001
That said, I prefer C++ as it allows me to easily delve into assembly for those times when performace is crucial
How very amusing.


I detect a note of sarcasm as I'm not sure how that is so amusing.
Promit
Promit
Quote:
Original post by Ryan_001
I detect a note of sarcasm as I'm not sure how that is so amusing.
There are maybe a dozen active members on these forums with the ability to out-code a compiler -- probably less. That you think you can write faster assembly than the compiler strikes me as dubious, at best. (And you can't claim SSE as a sanctuary -- intrinsics have a tendency to outperform hand written SSE.)
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Ryan_001
Ryan_001
Quote:
Original post by Promit
Quote:
Original post by Ryan_001
I detect a note of sarcasm as I'm not sure how that is so amusing.
There are maybe a dozen people on these forums with the ability to out-code a compiler -- probably less. That you think you can write faster assembly than the compiler strikes me as dubious, at best. (And you can't claim SSE as a sanctuary -- intrinsics have a tendency to outperform hand written SSE.)


I can give 3 concrete examples I myself have come accross where hand written assembly out performed or was required.

The first was an OS written for a university project. Very crude, but written completely from scratch (wasn't trying to re-invent the wheel, just learn by doing). The boot loader was written entierly in assembly (obviously), after which I jumped directly into C++. Most of the OS data structures (page tables, interrupts tables, ect..) were represented as classes, making it real easy to modify or change things. But its not like I could 'allocate' these classes as they represented fundamental structures that had to exist in certain locations in memory. And on top of it all there are things that u just cannot do at the intrinsic level, where hand coded assembly is required. Thre is no way I could have done that project in C#, its not only less efficient, but it would be completely infeasible.

The second was a hybrid VQ/DCT video compressor I made a few years back. Obviously choosing an optimal codebook is an NP complete problem, and there are a myriad of algorithms to do this out there. In order to compare them I wanted to compare them versus a nearly optimal brute force method (have something to base them against). But calculating it brute force method even for a very small sampling was taking forever (well almost a day for a single small image). Now my C++ code wasn't totaly optimal and I'm sure I could have sped it up a factor or 2 with intrinsics. But I went ahead and re-coded the core loop in assembly by hand, and was able to get a speed increase of around 100x - 1000x (would vary depending on the picture). One of the key instructions for this incredible speed increase wasn't even an SSE instruction but rather an obscure 3DNow extentsion, which to my knowledge u can't even reproduce using intrinsics. Also proper cache coherency is a requirement for high performance data processing, and u don't have the cache control using intrinsics that u do with assembly.

My third example comes from a project I'm currently working on, a library for distributed computing. I'm using (what I'd like to think, but probably isn't) a novel approach to the data marshalling problem. Rather than having an intermediate format, I rather use custom types with bit-wise guarantees. I have a generic template class which emulates the types and is compiler and platform indepedant. I then (obviously) overide the default implementation on systems where it is appropriate, and many tiems this includes assembly. Now I could probably use intrinsics here, but I personally find it easier to use inlined assembly. Also there are situations where I cannot have the compiler optimizing things, as I need to be able to guarantee things on a bit-wise level.

In all 3 of these situations, having the ability to use high level coding for 90% of the program, but then being able to get right down to nitty-gritty when needed was key. Now do I claim I can write better assembly than an optimizing compiler 99% of the time, no way. But that 1% of the time where performance is really needed, ya I can out-do a compiler, because I can do optimizations that they can't (and I know this because I do regularly de-compile my code and see what the compilers doing).

What I think is funny is how you're so quick to judge, u ranked me down before u even had a chance to see what I had to say. Apparently its impossible for me to have a reason to use C++ over C# eh?
Enselic
Enselic
I am convinced you are a very competent C++/Assembly programmer, but I highly doubt that the low level nature of C++ is an applicable argument for C++ on EmrldDrgn. If it is, then I am also conviced that EmrldDrgn would already know that.
nsto119
nsto119
If you *need* the speed of assembly and you're using C#, write it in C++ and P/Invoke.
CTar
CTar
Quote:
Original post by Ryan_001
The first was an OS written for a university project. Very crude, but written completely from scratch (wasn't trying to re-invent the wheel, just learn by doing). The boot loader was written entierly in assembly (obviously), after which I jumped directly into C++. Most of the OS data structures (page tables, interrupts tables, ect..) were represented as classes, making it real easy to modify or change things. But its not like I could 'allocate' these classes as they represented fundamental structures that had to exist in certain locations in memory. And on top of it all there are things that u just cannot do at the intrinsic level, where hand coded assembly is required. Thre is no way I could have done that project in C#, its not only less efficient, but it would be completely infeasible.

You couldn't have done it in C++ either, you'ld need assembly or a language which could write stuff like a bootloader (I haven seen such a thing). You could "easily" have done much of it in C#, you just need a compiler which can compile the code (Of course the compiler with Visual Studio wouldn't work). Microsoft Research actually made an OS in C# (well a derived language, but it was very close to C#), it's called Singularity. In this case assembly was required, and it didn't have anything to do with C++ or C#, it was pure assembly.

Quote:
The second was a hybrid VQ/DCT video compressor I made a few years back. Obviously choosing an optimal codebook is an NP complete problem, and there are a myriad of algorithms to do this out there. In order to compare them I wanted to compare them versus a nearly optimal brute force method (have something to base them against). But calculating it brute force method even for a very small sampling was taking forever (well almost a day for a single small image). Now my C++ code wasn't totaly optimal and I'm sure I could have sped it up a factor or 2 with intrinsics. But I went ahead and re-coded the core loop in assembly by hand, and was able to get a speed increase of around 100x - 1000x (would vary depending on the picture). One of the key instructions for this incredible speed increase wasn't even an SSE instruction but rather an obscure 3DNow extentsion, which to my knowledge u can't even reproduce using intrinsics. Also proper cache coherency is a requirement for high performance data processing, and u don't have the cache control using intrinsics that u do with assembly.

I can't really comment on this case considering that we haven't seen any code, but most compilers can help you making cache coherent code with compiler-specific extensions or just ordering the code correctly. Of course assembly offers way more flexibility, and if used correctly it can easily outperform current compilers, but not on a factor of 100-1000.

Quote:
In all 3 of these situations, having the ability to use high level coding for 90% of the program, but then being able to get right down to nitty-gritty when needed was key. Now do I claim I can write better assembly than an optimizing compiler 99% of the time, no way. But that 1% of the time where performance is really needed, ya I can out-do a compiler, because I can do optimizations that they can't (and I know this because I do regularly de-compile my code and see what the compilers doing).

I will have to agree with this current optimizing compilers are really bad, I think they even ignore most of the instruction set of the CPU (have you ever seen a SBB or ADC in compiler generated code?). Have you seen a compiler choose AL over AH because AL is faster? Compilers *should* be able to outperform hand-written assembly, but unfortunatly they can't.

T1Oracle
T1Oracle
I feel that with Boost Library + C++, you can get the benefits of C# while having the option to customize the way garbage collection and other finer details are handled where you need them to operate differently.

C# is most likely the superior choice for developing Windows software using a windows GUI.

C++ is a better choice when you need finer control over the lower level details.
Programming since 1995.
Ryan_001
Ryan_001
Quote:
Original post by CTar
You couldn't have done it in C++ either, you'ld need assembly or a language which could write stuff like a bootloader (I haven seen such a thing). You could "easily" have done much of it in C#, you just need a compiler which can compile the code (Of course the compiler with Visual Studio wouldn't work). Microsoft Research actually made an OS in C# (well a derived language, but it was very close to C#), it's called Singularity. In this case assembly was required, and it didn't have anything to do with C++ or C#, it was pure assembly.


The boot loader was done entierly in assembly (obviously), but as soon as the comp was in protected mode and enough of the executable loaded from the floppy disk (ya I booted off a floppy, it was the easiest method to learn on) I jumped right to the first function in my C++ program. Setting up all the memory structures (page, interrupt, tables, ect..) was all done in a combination of C++ and inline assembly. Nice thing about C++ is that with the linker I could happily add the assembly boot loader onto the front of the exe (ensuring the first 512 bytes were formated as floppy boot disks must be), and go from there.

Now correct me if I'm wrong, but isn't Singularily an OS desigend to natively run byte code type compilations ("abstract instruction set", is what they called it), but not built by it? Certainly interesting either way.

Quote:
Original post by CTar
I can't really comment on this case considering that we haven't seen any code, but most compilers can help you making cache coherent code with compiler-specific extensions or just ordering the code correctly. Of course assembly offers way more flexibility, and if used correctly it can easily outperform current compilers, but not on a factor of 100-1000.


I may have worded that wrong. I wasn't trying to imply C++ would get a 100x-1000x performance advantage over C#, or that my hand written assembly is 100x-1000x better than the compiler generated stuff. Rather it was a situation I had encountered where hand written assembly payed off, and I know that level of performance could not have been achieved through intrinsics alone. Mearly an example nothing more. As far as critiquing code goes, I think we've deviated far enough from the original question.

Quote:
Original post by CTar
I will have to agree with this current optimizing compilers are really bad, I think they even ignore most of the instruction set of the CPU (have you ever seen a SBB or ADC in compiler generated code?). Have you seen a compiler choose AL over AH because AL is faster? Compilers *should* be able to outperform hand-written assembly, but unfortunatly they can't.


And yet optimal code generation is an NP complete problem. Which means maybe they'll never be as good as a person.? Just a thought.

But I think I've hijacked this thread way too much at this point (as Enselic correctly pointed out ;). Back to to the original question.

EmrldDrgn, I think the real question is where do u plan on porting ur game. If windows is as far as it goes, then stick with C#, its easy, and more than fast enough for any normal game logic. If u want to program for other OS's / platforms (linux, GBA, whatever) then u will find C++ to be a much better choice IMO.
ToohrVyk
ToohrVyk
Quote:
Original post by Ryan_001
And yet optimal code generation is an NP complete problem. Which means maybe they'll never be as good as a person.? Just a thought.


What does NP-completeness have to do with being as good as a person? Persons don't even solve most P problems on their own.

Quote:

EmrldDrgn, I think the real question is where do u plan on porting ur game. If windows is as far as it goes, then stick with C#, its easy, and more than fast enough for any normal game logic. If u want to program for other OS's / platforms (linux, GBA, whatever) then u will find C++ to be a much better choice IMO.


For Linux, Mono and Tao/OpenGL work with C# as well.

It is true that C (and a certain, usually small subset of C++) exists on almost every single platform. In situations such as these (especially on the handheld market) hand-optimizing is a great plus, and memory management is best done by hand. On the other hand, developing on such platforms requires a great amount of skill — it's all in the wrist.
Arild Fines
Arild Fines
Quote:
Original post by Ryan_001

Now correct me if I'm wrong, but isn't Singularily an OS desigend to natively run byte code type compilations ("abstract instruction set", is what they called it), but not built by it? Certainly interesting either way.

No, it was primarily written in a superset of C#. There's a whitepaper on it which you can find on google.

--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
ronkfist
ronkfist
It's impossible to know which will perform faster. eg. If your gonna code C++ as you would in C# (dynamic allocation style) then C++ is gonna lose for sure. It all depends how good u are with both languages.

btw, actually it's easy to find out if hand written assembly performs better than compiled assembly...
Compile some code in C++ or/and C#, checkout the assembly, try to improve it by hand and add up the ticks it would take to execute each instruction. The least ticks wins and I'm pretty sure it will be the hand written one.
ToohrVyk
ToohrVyk
Quote:
Original post by ronkfist
Compile some code in C++ or/and C#, checkout the assembly, try to improve it by hand and add up the ticks it would take to execute each instruction. The least ticks wins and I'm pretty sure it will be the hand written one.


Sadly, while the least ticks do win (although I wonder what they win — free pie?), they are by no means the program with the shortest running time. Program speed is determined first and foremost by the amount processor cache trashing and pipeline stalling, and then by motherboard access times. The number of ticks in any instruction is hardly a significant value since pipelines allow you to do additional operations while waiting for the result of a long one — in effect, almost all operations last only one tick (the instruction itself) even though their result might be delayed for a short while. The only dangerous thing to do is stall your pipeline, which means it needs to wait for a result to do the next thing in line (at which point ticks become important, but you're screwed anyaway).

Because there is no possible prediction of the speed of a program except of running it, optimizers must act on heuristics.
Promit
Promit
Quote:
Original post by Ryan_001
The first was an OS written for a university project.
I think the OS point has been adequately covered. The selection of primary language doesn't even matter here.
Quote:
The second was a hybrid VQ/DCT video compressor I made a few years back. [...] But I went ahead and re-coded the core loop in assembly by hand, and was able to get a speed increase of around 100x - 1000x (would vary depending on the picture). One of the key instructions for this incredible speed increase wasn't even an SSE instruction but rather an obscure 3DNow extentsion, which to my knowledge u can't even reproduce using intrinsics. Also proper cache coherency is a requirement for high performance data processing, and u don't have the cache control using intrinsics that u do with assembly.
3DNow! intrinsics. First of all, you'll notice that intrinsics basically map directly to processor instructions (so your cache coherency claim is bullshit). The difference is that the compiler can understand intrinsics. This means a couple of things. First of all, it can make some alterations to the code before your 3DNow! function is called, as well as modifying the prolog and epilog for the function, so that you don't have extra pointless stack instructions lying around. Second, it can do the register allocation for you, which isn't necessarily difficult to do by hand, but it is tedious, error prone, and usually needs to be redone every time the code changes. Lastly, for a short 3DNow! or SSE function done with intrinsics, the compiler is able to go ahead and inline the function if it so desires - inlining is automatically disabled by inline assembly. It's because of these reasons that even Intel engineers, who probably know about beating a compiler better than anyone, use SSE intrinsics, not straight assembly.
Quote:
My third example comes from a project I'm currently working on, a library for distributed computing. I'm using (what I'd like to think, but probably isn't) a novel approach to the data marshalling problem. Rather than having an intermediate format, I rather use custom types with bit-wise guarantees. I have a generic template class which emulates the types and is compiler and platform indepedant. I then (obviously) overide the default implementation on systems where it is appropriate, and many tiems this includes assembly. Now I could probably use intrinsics here, but I personally find it easier to use inlined assembly. Also there are situations where I cannot have the compiler optimizing things, as I need to be able to guarantee things on a bit-wise level.
I don't really follow what's going on here, but I suspect that whatever you're doing could easily be handled in a higher level language. Apart from hitting privileged instructions and vectorized instructions, there aren't really any compelling reasons to involve machine instructions directly.
Quote:
In all 3 of these situations, having the ability to use high level coding for 90% of the program, but then being able to get right down to nitty-gritty when needed was key.
Which is an argument I don't really buy. Even so, you can integrate C++ and C# cleanly. So a C# program can involve hand written assembly if it's really honestly necessary (which it usually isn't).
Quote:
Now do I claim I can write better assembly than an optimizing compiler 99% of the time, no way. But that 1% of the time where performance is really needed, ya I can out-do a compiler, because I can do optimizations that they can't (and I know this because I do regularly de-compile my code and see what the compilers doing).
Compilers aren't perfect. Random unnecessary stack operations are common to see in the output, and there are certain scenarios (frequently related to instrinsic replacement of library functions) that don't get properly optimized at all. But unless you're doing something very out of the ordinary, those situations don't affect total program performance at all. None of the situations you gave merited assembly for maximizing performance.
Quote:
What I think is funny is how you're so quick to judge, u ranked me down before u even had a chance to see what I had to say.
No, I didn't. If I rated you down, it'd do a lot more than 11 points of damage.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
nagromo
nagromo
To get the topic back on track, use whichever you prefer. Well-written C# can be 5-10% slower than well-written C++ code, according to some benchmarks. Of course, this varies from program to program and is hard to properly measure, but the performance difference is fairly small.

One thing that can kill your framerate with C#, though, is constant creation and deletion of objects on the heap (types that are class, not struct). The more you do that, the more the garbage collector will have to run, which will slow down your game. As long as you create relatively few objects, though, you'll be fine. (By few, I mean don't create hundreds of new class objects per frame.)

One down side of using C# is that your users will have to have the .Net framework installed to run your program. They'll have to decide if the extra download is worth it for them.

If you're making a 2D game, check out BooGame, which will give you hardware-accelerated 2D via OpenGL, letting you do cool stuff like rotation, scaling, and transparency at high speed. It's also easy to use.

If you're using 3D, you can use Managed DirectX or Tao.OpenGL, or you could use a pre-made engine like Axiom. I'd suggest using a pre-made engine to really speed up the development process.

Good luck!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.