What kind of optimization makes C++ faster than C#?

Started by
65 comments, last by EddieV223 11 years, 3 months ago
I think the most obvious answer here is that the .NET runtime itself is written in C++.
So you can just write code directly in C++, or you can write code in C# that uses stuff written in C++ under the hood.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Advertisement
I think the most obvious answer here is that the .NET runtime itself is written in C++.
So you can just write code directly in C++, or you can write code in C# that uses stuff written in C++ under the hood.

I'm not really sure that's relevant. I could write a C++ compiler in python. Does that mean that the code generated by my compiler would be at least as slow as code running under python?

Continuous memory is also a big win for c++. When you make an instance of a class in c# it's really just a reference to the object on the heap. In c++ it exists on the stack unless you used new. This allows the computer to use the cache much more effectively. And with c++11 you can put these objects in say a vector and with move semantics efficiently have them moved around without problems or having to do a deep copy.

If this post or signature was helpful and/or constructive please give rep.

// C++ Video tutorials

http://www.youtube.com/watch?v=Wo60USYV9Ik

// Easy to learn 2D Game Library c++

SFML2.2 Download http://www.sfml-dev.org/download.php

SFML2.2 Tutorials http://www.sfml-dev.org/tutorials/2.2/

// Excellent 2d physics library Box2D

http://box2d.org/about/

// SFML 2 book

http://www.amazon.com/gp/product/1849696845/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=1849696845&linkCode=as2&tag=gamer2creator-20

Hi,

Just out of curiosity, I heard that game engine is mostly written in C++ because it is faster. But I don't know what kind of optimization C++ can offer over C#, can someone give some highlights so I can have general ideas of it

Regards
Getting back to the original post:

The myth that C# is inherently slower than C++ is exactly that: a myth.

There are similar myths that Java was inherently slower than C++, and they are also a myth.

Early compilers in both languages were very pessimistic in optimization and did generate slower binaries. Those very early tools have evolved.

There are facets of the libraries that are faster, and facets of the libraries that are slower. But the languages themselves are equal.



C++ is the core language in large part because experienced programmers know c++ and know how to get solid performance out of it. When engines must be cross-platform it is currently easier to use c++ because the third-party vendors provide c++ based interfaces; the network effect has locked that language in power for the time being. That is changing rapidly as many third party vendors are clearly moving toward C# as their preferred interface.


When you take an experienced c++ programmer and try to turn them into competent Java or C# programmers, there is a clear learning curve as they must re-learn what patterns are expensive to use and which are cheap.

It is easy to write poor-performing c# code if you are not familiar with the language, and most experienced game engine developers are not very fluent in c#. It is difficult for those experienced developers to make the transition.

Many of the up-and-coming developers are able to write more high quality code in C# than the experienced C++ developers could do in C++. Few developers need to know raw assembly any more because there are more productive tools out there. My studio has been mostly in C# for six years now, and the difference between our c++ and C# code is incredible. There was a brief learning curve and migration cost, but it has been more than made up for by performance in creating games. It is easier to put more in the game, and our results are at least as good. It is easier to find skilled C# programmers who can write performance-critical code than it is to find C++ developers who can do the same.

There is very clear motion in the works. From my perspective nearly all our tools are written in C#, and a good portion of our engine and most of our game code is written in C#. Mono runs great on all the major consoles, and there is no need for JIT compilation since the tools can emit the fully-optimized binaries if you pass the right arguments.

The OP (and many others) have just made the assumption that C# is slower or more cumbersome. I heard the same thing in the 90s that C++ was bloated and more cumbersome than C. I read the same arguments in the 80's that C was painfully slow and could never replace the skilled assembly-writing artisan.

The question has never been "will c++ be replaced", but "when". I believe we passed the tipping point a few years ago. It is now more difficult to get a seasoned C++ developer than to get a seasoned C# developer who is also more productive overall than that c++ developer.

Hi,

Just out of curiosity, I heard that game engine is mostly written in C++ because it is faster. But I don't know what kind of optimization C++ can offer over C#, can someone give some highlights so I can have general ideas of it

Regards

Getting back to the original post:

The myth that C# is inherently slower than C++ is exactly that: a myth.

There are similar myths that Java was inherently slower than C++, and they are also a myth.

Early compilers in both languages were very pessimistic in optimization and did generate slower binaries. Those very early tools have evolved.

There are facets of the libraries that are faster, and facets of the libraries that are slower. But the languages themselves are equal.

C++ is the core language in large part because experienced programmers know c++ and know how to get solid performance out of it. When engines must be cross-platform it is currently easier to use c++ because the third-party vendors provide c++ based interfaces; the network effect has locked that language in power for the time being. That is changing rapidly as many third party vendors are clearly moving toward C# as their preferred interface.







What you say about speed is just not accurate, c# and java are significantly slower when executing high work loads. There is a reason they develop their environments in c/c++. And there is a reason that hard ware manufactures write their drivers in c. These languages are faster, and are less waste full in memory as well.
When you take an experienced c++ programmer and try to turn them into competent Java or C# programmers, there is a clear learning curve as they must re-learn what patterns are expensive to use and which are cheap.

It is easy to write poor-performing c# code if you are not familiar with the language, and most experienced game engine developers are not very fluent in c#. It is difficult for those experienced developers to make the transition.

Many of the up-and-coming developers are able to write more high quality code in C# than the experienced C++ developers could do in C++. Few developers need to know raw assembly any more because there are more productive tools out there. My studio has been mostly in C# for six years now, and the difference between our c++ and C# code is incredible. There was a brief learning curve and migration cost, but it has been more than made up for by performance in creating games. It is easier to put more in the game, and our results are at least as good. It is easier to find skilled C# programmers who can write performance-critical code than it is to find C++ developers who can do the same.


A lot of what you say here is a bit whatever. However lets look at something. In windows 8 you can program in c++ however it is an interesting dialect of c++. There are no naked pointers. Instead they have what is really just a shared_ptr operator ^ .

This means there are absolutely no memory leaks in their version of c++. You can do this without using windows 8 if you wish. So you get the best part of C# in c++. It is rather genius I might add. And there is no need for garbage collection, everything is deleted properly. There is no garbage collector, and everything runs very fast. This is interesting because 2 of the major reasons developers chose c# over c++ is that c++ is very error prone due to miss use of pointers, including memory leaks. The other reason is that c# is easier to use. C++11's main goal was to clean up the language and make it easier to use, learn, and harder to create bugs. They really did a good job of that. So what you have here are the 2 of the top reasons people chose c# over c++ now fixed.

There is very clear motion in the works. From my perspective nearly all our tools are written in C#, and a good portion of our engine and most of our game code is written in C#. Mono runs great on all the major consoles, and there is no need for JIT compilation since the tools can emit the fully-optimized binaries if you pass the right arguments.
C++ is enjoying a huge resurgence because of c++11, even Microsoft creators of c# has been "Going Native". In fact they are so sold on c++ they have been investing in it. They paid for the new http://isocpp.org/ website for example, and have fitted the bill for many things the c++ organization needed this year.

The OP (and many others) have just made the assumption that C# is slower or more cumbersome. I heard the same thing in the 90s that C++ was bloated and more cumbersome than C. I read the same arguments in the 80's that C was painfully slow and could never replace the skilled assembly-writing artisan.

This is true, but what changed? Computers got faster, much faster and the cost of the more expensive language features became affordable.
The question has never been "will c++ be replaced", but "when". I believe we passed the tipping point a few years ago. It is now more difficult to get a seasoned C++ developer than to get a seasoned C# developer who is also more productive overall than that c++ developer.


Actually c++ is seeing a large resurgence in the industry due to being significantly upgraded to c++11, you realize that all these "Modern" languages have been getting patches and upgrades while c++ hasn't had new features added since 1998 and it still is in heavy use today, that says a lot. Not only has this changed with c++11 but they now have a complete structure in place to be able to release new upgrades to the c++ language every couple of years. In fact there are upgrades planned for 2013 and 2014

With that said, c# is a fine language, I like that language too. For a long time c# has been gaining ground and for good reason. It's been getting updated with features and things while c++ hasn't.

If this post or signature was helpful and/or constructive please give rep.

// C++ Video tutorials

http://www.youtube.com/watch?v=Wo60USYV9Ik

// Easy to learn 2D Game Library c++

SFML2.2 Download http://www.sfml-dev.org/download.php

SFML2.2 Tutorials http://www.sfml-dev.org/tutorials/2.2/

// Excellent 2d physics library Box2D

http://box2d.org/about/

// SFML 2 book

http://www.amazon.com/gp/product/1849696845/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=1849696845&linkCode=as2&tag=gamer2creator-20

In windows 8 you can program in c++ however it is an interesting dialect of c++. There are no naked pointers. Instead they have what is really just a shared_ptr operator ^ .

This means there are absolutely no memory leaks in their version of c++. You can do this without using windows 8 if you wish. So you get the best part of C# in c++. It is rather genius I might add. And there is no need for garbage collection, everything is deleted properly. There is no garbage collector, and everything runs very fast.

The "^" operator isn't equivalent to a shared_ptr (if it were, you would have a ton of leaks, because shared_ptr's can't cope with circular references, and require the programmer to be able to explicitly choose between them and weak_ptrs...), it's exactly equivalent to C# references!
The dialect you're talking about is called C++/CLI, and it is compiled to MSIL -- the same intermediate "bytecode" language that C# is compiled to, and it runs on the same VM and uses the same Garbage Collector that C# does!

Scratch that!

The OP (and many others) have just made the assumption that C# is slower or more cumbersome. I heard the same thing in the 90s that C++ was bloated and more cumbersome than C. I read the same arguments in the 80's that C was painfully slow and could never replace the skilled assembly-writing artisan.


This is true, but what changed? Computers got faster, much faster and the cost of the more expensive language features became affordable.

What changed is that C compilers got smarter and smarter, to the point where they can now write assembly as well as experts can (when given sensible inputs). Likewise, C++ compilers got smarter and smarter, to the point where they matched C compilers.
Following the same tradition, C# compilers are also getting smarter.
Take note that because C# is a lot more restrictive on the programmer, operating on a completely different kind of 'abstract machine' to C/C++, the compiler actually has a lot more information available to it when making optimisation decisions.
e.g. C++ code can look pretty innocent, but still cause a lot of confusion for the compiler. As a straw-man, take this function:


void World::FindPlayerWithMinHealth( int& outHealth, int& outIndex )
{
 outIndex = -1;
 outHealth = 100;
 for( int i = 0; i != m_players.size(); ++i )
 {
  if( m_players[i].health <= outHealth )
  {
    outIndex = i;
    outHealth = m_players[i].health;
  }
 }
}

And then I call it with:


world.FindPlayerWithMinHealth( world.m_players.m_size, world.m_players.m_size );

When the compiler is compiling the function, it has to do it in such a way that the stupid line above will behave as expected. So, looking at it again:


void World::FindPlayerWithMinHealth( int& outHealth, int& outIndex )
{//these two lines could change any bit of memory anywhere in the system!!
 outIndex = -1;
 outHealth = 100;
 for( int i = 0; i != m_players.size(); ++i )//m_players.size() has to be re-called every iteration, perhaps it's value has changed.
 {
  if( m_players[i].health <= outHealth )//have to fetch m_players.begin every iteration, perhaps it's value has changed
  {//these two lines could change any bit of memory anywhere in the system!!
    outIndex = i;
    outHealth = m_players[i].health;//have to fetch m_players[i].health again, even though it just appeared above.
  }
 }
}
In windows 8 you can program in c++ however it is an interesting dialect of c++. There are no naked pointers. Instead they have what is really just a shared_ptr operator ^ .

This means there are absolutely no memory leaks in their version of c++. You can do this without using windows 8 if you wish. So you get the best part of C# in c++. It is rather genius I might add. And there is no need for garbage collection, everything is deleted properly. There is no garbage collector, and everything runs very fast.

The "^" operator isn't equivalent to a shared_ptr (if it were, you would have a ton of leaks, because shared_ptr's can't cope with circular references, and require the programmer to be able to explicitly choose between them and weak_ptrs...), it's exactly equivalent to C# references!
The dialect you're talking about is called C++/CLI, and it is compiled to MSIL -- the same intermediate "bytecode" language that C# is compiled to, and it runs on the same VM and uses the same Garbage Collector that C# does!

If he's talking Windows8, he's probably talking about C++/CX, which looks basically identical to C++/CLI, except doesn't compile to .NET code, and in C++CX, the ^ hat symbol *is* used to denote something akin to shared_ptr (it uses refcounting), and suffers from the circular reference problem (they introduced WeakReference to deal with this)

http://en.wikipedia.org/wiki/C%2B%2B/CX

What you say about speed is just not accurate, c# and java are significantly slower when executing high work loads. There is a reason they develop their environments in c/c++. And there is a reason that hard ware manufactures write their drivers in c. These languages are faster, and are less waste full in memory as well.

Let's not forget the context of a game engine, shall we?

I'd love to see some actual research showing that "c# and java are significantly slower when executing high work loads." Major companies like IBM and Oracle have neatly debunked that for Java. If you are looking for corporate database work you'll be doing it in Java. Microsoft did a fairly good job of debunking that for C# back in 2005, but it hasn't really sunk in yet.

You certainly can do many things in c++ that you cannot do in the other languages. Pointer manipulation and knowledge of the hardware can give you a performance advantage. This is much like the highly skilled assembly artisan of yesteryear.

However, let's consider how c won out over assembly. It certainly isn't faster to execute, at best it can match what the expert artisans produced. No, that isn't it. C took over because of its ability to develop software much more rapidly and in a way that did 't require expert artisans. The computers were faster and could spare the extra cycles that might be introduced by translating into machine code, the main cost of software was all the gruntwork, and that could be dramatically reduced with c. Those few places that needed to be hand-tuned by artisans could still be tuned, while the bulk of the work done more rapidly and with fewer bugs (read: cheaper) than the assembly counterpart. It also helped that you only needed to port a very tiny portion of code to move to new hardware, but in practice that wasn't much of a selling point.

Over the years new hardware features were exposed and were only available to assembly developers, but gradually those were made available to c programmers through libraries and later through compiler-specific features and options.

When C started to lose to c++ many of these same arguments appeared. It was bloated, it couldn't match what the expert artisans produced, it forced extra overhead with virtual tables, name resolution was a mess, and on and on and on. Yet the same factors caused its victory: The computers were faster and could spare the extra cycles that might be introduced in translation, the main cost of software was all the gruntwork, and that could be dramatically reduced with c++. Those few places that needed to be hand-tuned by artisans could still be tuned, while the bulk of the work done more rapidly and with fewer bugs (read: cheaper) than the c-based counterpart.

Over the years now hardware features were exposed and were only available through limited means, but gradually they were promoted to intrinsic operations and other compiler-specific features.

We are now seeing exactly the same thing with C#. Much of the business world saw this with Java, but games did not make that move. It is certainly true that an artisan in C++ or C can often craft slightly faster bits of code with those languages than with C#. However, computers are faster and can spare the extra cycles., the main cost of software is still all the gruntwork, and it can be done both faster and safer with C#.

The c++ artisan can do amazing things. Templates were often derided as a source of bloat, and then when template metaprogramming came around these artisans could produce code that compiled neatly but at a cost... Build times for some projects skyrocketed. The biggest pile of heavily optimized c++ I've ever worked on required nearly two full days on a build farm to compile. Sure the code was nice and fast, but when the turnaround takes so long the cost of development suffers.

Is there a place for these people in games? Certainly! There is a segment of the engine that needs heavily optimized code. But as we are discovering at my studios and others around the globe, that portion of the engine is extremely small and rapidly vanishing.

Something else is subtly different with C#. Java very nearly did this, but Sun couldn't quite manage to do it. Microsoft managed it: They constrained the language to work on a platform agnostic virtual machine. They forced the developers to live with some very tight constraints that many people don't like. But the constraints are more like the rules of art that enable more creative works to come from them: The constraints give us automatically-parallelizing compilers that can automatically split the work, balance it between processors, and do so just as well as the artisans of today can do --- with fewer bugs. The constraints enable code to re-write and re-optimize itself at runtime with no effort from the developer. We (and many other studios) have found that Mono on consoles is a great thing; we have ported to X360, PS3, Wii, WiiU, and even 3DS amazingly enough, and managed to do it for less cost than we expected because the core of the game targeted the C# virtual machine.

Tools developers have taken notice. Middleware is now touted with being CLR-friendly. Many developers are actively pushing on Sony and the other console developers for direct C# support. A rapidly increasing number of studios want access to hardware-specific functionality in c# compilers. And it is only a matter of time before that happens.

There are still features missing from the language, but that is true of all languages be it C++, Python, or Ruby. Sometimes you still need that tiny little boost a bit of assembly will give you. But those times are extremely rare.




Concluding this rather wordy post:

Talk with recruiters and headhunters, pay attention to the jobs and want ads, and you will notice that the only c++ programmers in demand are the artisans. Sure there is still gruntwork to be done in the language, but it is much dimished. The gruntwork of game development is rapidly moving away from C++. Sure the language has many great things, and I've made years of my living from being a language lawyer myself; but that time has passed. Our studio -- and many others -- paid the cost of porting to C#, and I can personally attest to the improvements it has made in what we can do. Not because the language generates magically different executables, but because the gruntwork can be done cheaper.

And when it comes to game development, cheaper will always win.
this rather wordy post

Excellent post!

I'd like to point out a few things that might not be accurate:
When C started to lose to c++ many of these same arguments appeared. It was bloated, it couldn't match what the expert artisans produced, it forced extra overhead with virtual tables, name resolution was a mess, and on and on and on.

Ignoring the name resolution mess, which has not much to do with the performance debate, there's still a difference between the additional features that C++ adds over C compared to what C# adds to C++.

First, let's look at a few things that C++ brought to the table:
OOP, including runtime polymorphism via ("virtual"), overloading, RTTI, exceptions and templates.

All of these are concepts that were possible to implement in C and integrated them into the language, while retaining the "do not pay for what you do not use" approach. Everything is optional, some things are even cost free, for example overloading, all of OOP, except runtime polymorphism and, for most part, templates. C++ introduced a multi paradigm approach to programming, which seems to confuse a lot of programmers, but is, in my opinion, essential to most often get the best tool for a certain job.

Now, let's see what C++ took away from C:
Nothing! Well, not strictly true, but nothing that really affects anyone.

One might argue, that it should have removed more stupid stuff from C, but then again, remember the "do not for what you do not use" approach, which makes all leftovers, by definition, benign.

Moving on to the differences between C++ and C#/Java.
What did they add?
Fully automatic memory management through GC, a VM for standardization of data types and interpretation or JIT compilation of "byte code", full reflection

Since they are not really an evolution over C++ or C, the comparison is a bit trickier. All of the improvements come with their penalties and are not optional. Every dereference operation has to go through an extra indirection to find out where the memory actually is, the compiler can't really throw stuff away, because the program can still access everything that has been in the source code through reflection, including the names and the VM makes access to system resources that are not already supported tedious or even impossible.

What has it taken away?
Free functions, templates (except for what generics cover), manual memory management, multiple inheritance (except interfaces), and more.

No I'm not saying these are all good or useful things to have, but I'd rather have the options and not be forced into a behaviour that suits the mindset of the creators of the language. Java was created when OOP was kinda new to the mainstream and "teh future", but now it's an old thing and there's a tendency to go data driven programming, for instance.

Some things that it takes away are downright bad:
The RAII idiom is no longer possible, because there's no way to tell when exactly objects are destroyed (C# works around that somewhat with "using"), the GC is unpredictable and introduces nasty pauses when not managed very carefully and there's no way to manage memory manually _at all_ (like, *gasp*, put in on the stack).

The attempt to push the vast subject of programming into a tight set of rules is what upsets me most about these "new" programming languages. I'd hope that something will come along, that adds new goodies, but keeps the old ones.
Tools developers have taken notice. Middleware is now touted with being CLR-friendly. Many developers are actively pushing on Sony and the other console developers for direct C# support. A rapidly increasing number of studios want access to hardware-specific functionality in c# compilers. And it is only a matter of time before that happens.

You know, popularity is not a good indicator of how good something is at something. Take a look at Cobol or, ironically, C or C++. ;)

Not because the language generates magically different executables, but because the gruntwork can be done cheaper.

Not sure what exactly you mean by grunt work, but if it's something un- or lesser skilled people can do, then it should be automated, regardless of language used. Remember, work smart, not hard! ;) j/k
C++ operates at a lower level of abstraction than C#. In C++, you could (if you wanted to) trivially fill an array with machine code, cast it to a function and run that code (it would no longer have any amount of portability at that point).

This worked with W95 the last time. Execution of data segments is not allowed in any OS available for the broad market.

It may work with OS that are designed for the embbedded market, but normally this is not working anymore.

I did that the last time for a Win-3.11 application written in C and at that time no one thought of C++.

This topic is closed to new replies.

Advertisement