steveth45![]() Member Posts: 536 From: Eugene, OR, USA Registered: 08-10-2005 |
(This is a repost, since the other topic was difficult to respond to because of the # sign in the title) I've always promoted C++ as the ultimate game programming language, but recently I've been eating my words. Allow me to explain. I've been planning on writing an RPG that parses normal English expressions. In preparation, I wanted to find the fastest way to look up a word from an associative list so I can read in a word and quickly access related game data. I thought C++ / STL would be the fastest solution. So, I wrote a little program that loads a long list of words from a text file (about 110,000), puts them into an associative list and then does a bunch of random searches. On the C++ side, I used a "stdext::hash_map" and the "std::string" object. I thought I had found the fastest way until, after discussing the issue with HanClinto, a big C# and .NET proponent, I decided to do a comparison. Using SharpDevelop I created a similar program using a "Hashtable" and the "string" type. Both programs ran so fast that I had to set the number of random searches to 1,000,000. Here is the output: (C++ w/ STL - compiled with Visual C++ 2005 Express) (C# compiled with .NET 1.1 in SharpDevelop) C# wins on all counts. Both Han and I had fully expected C++ to be faster. I've emailed the code for both programs to Han, and he's going do the same test in Linux with GCC compiling the C++ code and Mono compiling the C# code. As far as simplicity goes, the C++ code was slightly longer (a few lines) and the Hashtable in C# was a little simpler to implement than the stdext::hash_map. Any thoughts on this? ------------------ [This message has been edited by steveth45 (edited May 30, 2006).] |
||
SSquared![]() Member Posts: 654 From: Pacific Northwest Registered: 03-22-2005 |
Amen bro! You see the light. ;-) It's possible a lot of the speed may be related to memory allocation which is actually faster in managed code than C++. I assume you are using ever-expanding hash tables and lists that grow as needed. Try creating everything with their correct size FIRST so there is no extra allocation necessary. That way you can remove memory allocation from the equation. Although there is still the memory allocation for each word read from the file. Which reminds me, perhaps file I/O is faster in .NET, and may explain the rather large time discrepancy in the two timings when reading in from the file. But that is pure speculation on my part. I guess the larger and more interesting issue is with the retrieval time. Perhaps the C# Hashtable uses a faster optimization to find an item. Also, try not to use a random search. Doing a sequential search through each item will force both programs to be running the same type of sequence of steps. The C# Hashtable may also be speedier at the expense of memory usage. Also, I noticed the C# version read in ONE less word than the C++ one. That might really speed things up too. :-) |
||
buddboy![]() Member Posts: 2220 From: New Albany, Indiana, U.S. Registered: 10-08-2004 |
hmm... i figured C# would win, even tho i use C++ myself =D... but i am somewhat learning C#, since i started using MITE =D... ------------------ |
||
CoolJ![]() Member Posts: 354 From: ny Registered: 07-11-2004 |
I've always been interested in knowing how C# stacks up with C++ too. I found this link showing comparison execution time/memory usage of various languages doing various operations. What's cool is if you click on a operation, then click on the name of one of the languages listed, it will show you the code they ran for the operation..cool, so you could use their example code to do your own check I guess. This link has a nice summary of different operation performances with |
||
HanClinto![]() Administrator Posts: 1828 From: Indiana Registered: 10-11-2004 |
Grrr.... I got the cpp file pretty far, but then I got this error: I tried fixing it the way this guy mentioned: /tmp/ccMHLAJh.o(.gnu.linkonce.t._ZN9__gnu_cxx13new_allocatorINS_15_Hashtable_nodeISt4pairIKSsSsEEEE10deallocateEPS5_j+0xd): And loads of other goodness. That's only 2 lines from it! There were Also found a link to a bug about it in GCC: "RESOLVED WONTFIX" :-\ So looks like one would have to write their own hashing algorithm for However, the csharp stuff worked great!
So as expected, Linux is a little bit slower, but not *too* much so. The part where it really loses is in the file access bit though, which kindof surprises me. I'd still be interested in seeing how well C++ did, but at least we've got a [This message has been edited by HanClinto (edited May 31, 2006).] |
||
HanClinto![]() Administrator Posts: 1828 From: Indiana Registered: 10-11-2004 |
Okay, cool. A friend of mine (one of the office Linux gurus) looked at the results, and had a couple things he guessed about it. He said something similar to SSquared in that managed languages handle memory better. He didn't emphasize the allocation as much as the deallocation, because managed languages hold off deallocating memory until they do their lump garbage collection which can be faster than just nickle and diming with a bunch of little deallocations. He also said that the file read time discrepancy between Linux and Windows is likely because my Linux install is using the default Linux file access configuration (which it is). He said that Linux comes with default "slow but safe" hard drive access parameters. He also pointed me to an article on the subject that he said was 6 years old but still relevant. I imagine that Windows does some of this access optimization automatically, and now I'm kindof curious to know how well Linux would do if I ran hdparm and optimized my settings. Cheers! --clint |
||
SSquared![]() Member Posts: 654 From: Pacific Northwest Registered: 03-22-2005 |
This is some great information. Those links were really interesting, coolj. Funny. It seems the two things C# shows itself faster than C++ are with hashtables and file I/O. The two very things Steveth45 was comparing. It was pretty cool to see the Linux vs. Windows results HanClinto. For an absolutely fascinating read (at least I think so) on .NET's garbage collection, read the following: http://msdn.microsoft.com/msdnmag/issues/1100/gci/ The information pertaining to memory allocation speed is right at the top in the section titled "Resource Allocation". Keep in mind, this is specific to Microsoft's CLR. This is NOT the same as what Java uses. Unfortunately, I do not remember the exact details of Java's GC implementation, but I do recall it being different. I just wouldn't want people thinking if they've read one article on GC, then it is the one and only way to do it. |
||
Jari![]() Member Posts: 1471 From: Helsinki, Finland Registered: 03-11-2005 |
I had to instantly doubt that C# would be faster than C++ because usually higher level languages are slower. From what I found from google it appears that speed comparison isn't that simple thing, see this page for instance (C#,C++ and java compared): http://www.tommti-systems.de/go.html?http://www.tommti-systems .de/main-Dateien/reviews/languages/benchmarks.html C# has the fastest hashmap but slow matrix multiply and nested loops. ------------------ [VoHW] (Help needed) [Blog] - Truedisciple (mp3) [This message has been edited by jari (edited May 31, 2006).] |
||
steveth45![]() Member Posts: 536 From: Eugene, OR, USA Registered: 08-10-2005 |
I'm impressed with Mono's performance. That validates the use of C# as a cross-platform game development language. I'd probably never try to use it for a 3D game since those depend heavily on matrix multiplication plus you'd see a hiccup in the frame-rendering whenever garbage collection occurs. I suppose if you did the rendering and physics backend in non-managed C++, there's no reason not to write other parts of the code in C#. The capability of C# to compile and link to new classes during runtime gives it a built-in scripting framework, as Han has done with MITE. Maybe this discussion will encourage some people to take a second look at C#. I, for one, am seriously considering using it in my next game project. ------------------ |
||
CoolJ![]() Member Posts: 354 From: ny Registered: 07-11-2004 |
Does it appear to you that memory usage for c# is 4x to 10x higher than c and c++? That could be a significant factor. However maybe this is due to .net being loaded. I don't know. | ||
HanClinto![]() Administrator Posts: 1828 From: Indiana Registered: 10-11-2004 |
quote: One thing that especially impressed me about C# during this test Steve was that with even a fairly small and simple C++ application like this test that you wrote, I still had to make a fair number of changes to get it to compile under Linux (and I never quite got it). For C#, I just copy/pasted and it worked flawlessly under Linux and Windows first time (well, second time -- the first time I forgot to put the word file in the directory). That ease-of-use is wonderful. No ./configure -- no hokey makefiles, no gcc version discrepancies -- just compile and run. It's for reasons like that that interpreted languages have my vote for cross-platform game development all the way. I totally agree about the rendering engine -- let it be written in C++ for performance (like how Irrlicht, Torque and pyGame do it), but I never want to go back to writing gameplay code in C++. --clint |
||
HanClinto![]() Administrator Posts: 1828 From: Indiana Registered: 10-11-2004 |
quote:
But my desktop has 512 megs of ram, and my laptop has a gig -- memory's not an issue for me. Speed is important -- not performance so much, but mainly speed of development. That's why I like C# -- I can just operate so much more quickly than in C++. --clint |
||
dartsman![]() Member Posts: 484 From: Queensland, Australia Registered: 03-16-2006 |
wow, great topic, although I always had thought comparing the two is like comparing C++ and Java... they are really two seperate languages... these are some pretty good results. I was actually thinking about writing libraries in C++ for game engine side of things and then using the libraries in C# as I could do some rapid application development (GUIs) and such in C# much faster then in C++... I will definately do that now, as it looks like C# isn't as silly of an idea anymore :P Great work guys, hope others also start looking into C#, it's great especially for getting apps done, but seems a bit more flexable then VB... could just be me :P ------------------ |
||
HanClinto![]() Administrator Posts: 1828 From: Indiana Registered: 10-11-2004 |
Horray! I was able to get it to compile with g++ (I was trying to use gcc before). So here's the output from the c++ run on Linux:
And another run of the c# one for good measure.
So I'm glad we've got the comparison now for Linux. Fun stuff! --clint |
||
CoolJ![]() Member Posts: 354 From: ny Registered: 07-11-2004 |
From what I read, it looks like the default setting for the hash_map might be optimized for smaller # of items (less mem) as opposed to C#. But this can cause bucket collision. Try adding the following to your c++ file, and see if you get any performance improvement:
struct new_comp // *** example usage*** // int main() [This message has been edited by coolj (edited June 01, 2006).] |
||
steveth45![]() Member Posts: 536 From: Eugene, OR, USA Registered: 08-10-2005 |
Wowza, G++ got stomped by Mono in Linux regarding hash efficiency, except that it did load the file faster. Coolj, We are using std::string, not const char*, but it may work with minor tweaking because std::string is basically a wrapper for char*. ------------------ |
||
steveth45![]() Member Posts: 536 From: Eugene, OR, USA Registered: 08-10-2005 |
OK, Coolj, I got your code to work with std::string Here it is:
It is just a little slower than the default implementation in VC++. It did the search in 969 ms instead of 922 ms. It did work, though, and it may give Han a significant speed boost if the slowness of the G++ implementation is due to an inefficient algorithm for larger maps. ------------------ |
||
CoolJ![]() Member Posts: 354 From: ny Registered: 07-11-2004 |
SLOWER!!! ARGG! lol! ![]() I did notice you change min_buckets from 65536. It suppose to be a power of 2....oh well, I doubt it would matter much! |
||
steveth45![]() Member Posts: 536 From: Eugene, OR, USA Registered: 08-10-2005 |
Yeah, I doubled the bucket size. Actually, it was the same speed, either way. ------------------ |
||
NileCoder![]() Junior Member Posts: 8 From: winter park, fl, 32792 Registered: 03-20-2004 |
Here is something you should know. STL (standard template libary) was not designed for speed, but for flexibilty. C++ is 10 times out of 10 faster than c#. Why?? It's how many layers of interfaces you have to go through to get at the hardware. C# has more than c++. Try the same test, write your data structures to deal with the string search, and see what your results are. ------------------ |
||
fearless![]() Member Posts: 91 From: Romania, Tg Mures Registered: 11-26-2005 |
For those interested in the subject, I found this thread a while ago on GameDev. There are some good points made there in favor of C# (you'll have to read through a bit) | ||
HanClinto![]() Administrator Posts: 1828 From: Indiana Registered: 10-11-2004 |
Good read, thanks Fearless! I found it cool that they mentioned the Reality engine way back then, and that's the same engine that Xcrucifix and Boanerges are using to develop their Christian games now. Very cool. --clint |
||
steveth45![]() Member Posts: 536 From: Eugene, OR, USA Registered: 08-10-2005 |
One of the reasons the C++ code was slower than the C# code in the word search algorithm is that C# strings are immutable, so all the copying around is just creation of new references on the stack, not actual heap allocations which the C++ code was doing one or two of every loop. Now, when you change a string somehow in C#, then it creates a new string in a different place in memory and reassigns the reference. This means the C++ was doing significantly more work. I did a quick test of this, and by changing the C++ code to not copy around strings each loop but use references instead, it ran significantly faster. ------------------ |
||
HanClinto![]() Administrator Posts: 1828 From: Indiana Registered: 10-11-2004 |
quote: Interesting, Steve -- how much faster? Faster than C#? --clint |
||
steveth45![]() Member Posts: 536 From: Eugene, OR, USA Registered: 08-10-2005 |
quote: Not quite. The cpp code takes 828 ms now, instead of 922. C# is still faster for me at 734 ms. But it's within spittin' distance. ------------------ |
||
CPUFreak91![]() Member Posts: 2337 From: Registered: 02-01-2005 |
Is there any chance I could get ahold of a copy of those two programs? I'd like to try them on my new laptop and on my old desktop. ------------------ "Oh, bother," said the Borg. "We've assimilated Pooh." "Socialism works great... if there are no people involved." -- Pastor David Ginter, Union Church of Guatemala. |
||
steveth45![]() Member Posts: 536 From: Eugene, OR, USA Registered: 08-10-2005 |
the C Pound:
The Double Plus:
------------------ |