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

is C++ faster than java? And is a language really a language without its legacy?

Started by Rickert Feb 16, 2011 at 6:51 PM 17 replies 5.4k views
Original Post
Rickert
Rickert
I am still in the learning process. I studied and programmed in Java from the beginning up until now is almost 2 years. Made several GUI applications, some games with threads and networking (my assignments). I am going to study C++ next, and I am interested in it because C++ is the language which is used primary in game industry, so maybe I'm gonna heavily investing time in it. I also did a little research on C++ vs Java as well as other languages, and I read other threads in this forum about this subject. Usually, the conclusion is C++ faster in most cases, except for lab benchmarks. However, I tried a little program, and C++ (using std::cout from iostream) is slower than Java, but faster than java using printf from C:

Java code:



public class Main {
public static void main(String[] args) {
int count = 0;
for(int i= 0; i< 200000; i++)
{
System.out.println("Hello world!");
count++;
}
System.out.println("Count:"+count);
}
}


Result: On my system, it completed in 42 secs.

C++ code:
  • With std::cout



    #include <iostream>
    using namespace std;

    int main() {
    int count = 0;
    std::ios_base::sync_with_stdio(false);
    for(int i = 1; i < 200000; i++)
    {
    cout << "Hello world!\n";
    count++;
    }
    cout<<"Count:%d\n"<<count;
    return 0;
    }



    Result: It took forever, so I stopped before it could even finish. I already turned off sharing with stdio from C to speed up significantly.
    • With printf


      #include <iostream>
      using namespace std;

      int main() {
      int count = 0;
      for(int i = 1; i< 200000; i++)
      {
      printf ("Hello world!\n");
      count++;
      }
      printf("Count:%d\n",count);
      return 0;
      }


      Result: Less time to finish compare to Java.

      So, should I stop using iostream and used the C stdio?

      Also, some people argued that C++ is popular because of its legacy. But, is the language completed without its legacy? Will Java be Java when Java API does not exists anymore?
Antheus
Antheus
Wrong question.

For a given set of parameters, which will complete fastest: System.out.println(), std::cout or printf().

Answering this question alone is a matter of very involved study. Language has next to no impact on results.

std::cout in your case is almost certainly slow due to one of two reasons:
- safety checks on iterators, which increase constant factor on container operations
- synchronization between C stdio and iostreams, which can be disabled
- implicit conversion from const char * to std::string on each invocation

The latter point warns of dangers of implicit behavior present in C++.

Try:
int main() {
int count = 0;
const std::string S = "Hello World\n";
for(int i = 1; i < 200000; i++)
{
cout << S;
count++;
}
cout<<"Count:%d\n"<<count;
return 0;
and

int main() {
int count = 0;
const char * s = "Hello World\n";
for(int i = 1; i < 200000; i++)
{
cout << s;
count++;
}
cout<<"Count:%d\n"<<count;


C++ is notoriously difficult precisely due to such hidden pitfalls.

As a rule of thumb - if juggling a lot of small temporary strings, Java will probably win out. C would likely avoid most of such allocations through extensive use of stack, but at expense of considerably more verbose code for even the simplest operations.

So, should I stop using iostream and used the C stdio?[/quote]If you want to learn C++, you need to learn C++. Warts and all. Learning C is also a viable option, but that is a separate thing. Beyond superficial level, idiomatic and domain-specific C and C++ have surprisingly little in common.

Will Java be Java when Java API does not exists anymore?[/quote]Java Standard Library cannot be separated from the language - or it cannot be called Java. See the recent lawsuits concerning that.

For something to call itself Java it needs to be licensed from Oracle which confirms that implementation meets the requirements.

There is no such thing in C++ or C.


At some point I was dealing with some code that was dumping a lot to file. Between fwrite, fstream.fwrite, sprintf and many other variations, there is no clear cut winner. Each of them can be used in a way that will exceed the throughput of disk, but it depends a lot on too many details to be possible to generalize.
Sirisian
Sirisian
There are a few mishaps that happen when beginners try to benchmark things. Often they don't turn on release mode since debug mode has a lot of checks to assist the programmer.


So, should I stop using iostream and used the C stdio?

Your program outputs to the console a lot? Also again make sure you're in release mode.

Also, some people argued that C++ is popular because of its legacy. But, is the language completed without its legacy? Will Java be Java when Java API does not exists anymore?

C++ is "popular" because it's used a lot and gives programmers a lot of control. For instance assembly SSE intrinsics for doing math heavy operations are easily accessible while in languages like C# they're nonexistent. Also with modern libraries, like boost, using C++ is very similar to using any other language as long as you don't get meta-programming happy or become a clever C++ programmer.

In before language war.
Mike.Popoloski
Mike.Popoloski
Console output is a pretty stupid thing to benchmark, since there is so much going on behind the scenes of which you aren't aware. For example, most console output is buffered. If you add the following lines at the start of your iostream example, it completes in less than 10 seconds:


char buffer[1024];
cout.rdbuf()->pubsetbuf(buffer, 1024);


Which is silly of course, because who writes a program that dumps that much raw information to the console? Point is: artificial benchmarks are dumb. Write it properly using idiomatic code, and then optimize things later if your profiler points to it as a hotspot. Standard advice really that a dozen other people are going to repeat after me, but there it is.
Mike Popoloski | Journal | SlimDX
Antheus
Antheus

Which is silly of course, because who writes a program that dumps that much raw information to the console?


Well, I did. Console tools and shell pipes. They fit perfectly into any *nix toolchain.

And it's typically not a problem until you suddenly start dealing with giga or terabyte-sized files.

The only general lesson I could take away from that was: buffer as much as possible in memory, dump in as few calls as possible. 16MB buffer is good, 64 is better, 256 works even better. Then dump that directly.
Mike.Popoloski
Mike.Popoloski

[quote name='Mike.Popoloski' timestamp='1297883332' post='4775067']
Which is silly of course, because who writes a program that dumps that much raw information to the console?


Well, I did. Console tools and shell pipes. They fit perfectly into any *nix toolchain.

And it's typically not a problem until you suddenly start dealing with giga or terabyte-sized files.

The only general lesson I could take away from that was: buffer as much as possible in memory, dump in as few calls as possible. 16MB buffer is good, 64 is better, 256 works even better. Then dump that directly.
[/quote]

At that point you might as well use memory-mapped files, no?
Mike Popoloski | Journal | SlimDX
Rickert
Rickert
Ok thanks for response and clear my confusion. I don't intend for a language war, because we know that languages are just tools, and are suitable depends on problems we are trying to solve. It's just I wanted to try and found it was a little strange.

Edit: The topic title might be misleading, so I'm gonna change it. But too bad, I can't change. Hope some moderators can change it to more casual like: Console Output test between C++ and Java and speed factors etc...
Antheus
Antheus


At that point you might as well use memory-mapped files, no?


That would require involving disk.

Consider log parsing or such. Take tar.gz, pipe it to one tool, pipe it to other, then third, then dump the summary. Or having data piped over sockets through a SSH session to remote machine or such.
Antheus
Antheus

Ok thanks for response and clear my confusion. I don't intend for a language war, because we know that languages are just tools, and are suitable depends on problems we are trying to solve. It's just I wanted to try and found it was a little strange.


Try this out:public class TestConsole {

public static void main(String args[]) {
try {
FileWriter fw = new FileWriter("results.txt");
long a = System.currentTimeMillis();
int count = 0;
for(int i= 0; i< 20000; i++)
{
System.out.println("Hello world!");
count++;
}
System.out.println("Count:"+count);
fw.write("Time taken: " + (System.currentTimeMillis() - a) + "\n");
long b = System.currentTimeMillis();

StringBuffer sb = new StringBuffer(65536);
for(int i= 0; i< 20000; i++)
{
sb.append("Hello world!\n");
if (sb.length() > 64000) {
System.out.println(sb);
sb.delete(0, sb.length());
}
count++;
}
System.out.println("Count:"+count);
fw.write("Time taken: " + (System.currentTimeMillis() - <img src='http://public.gamedev.net/public/style_emoticons/<#EMO_DIR#>/cool.gif' class='bbc_emoticon' alt='B)' /> + "\n");
fw.flush();
} catch (Exception e) { }
}
}


Results from my machine:
Time taken: 8704
Time taken: 1072[/quote]
Or, using simple buffer increases throughput by a factor of 8. Same would apply to C and C++.
Fiddler
Fiddler
I think the OP and the consequent answers show a very important lesson: C++ can be made to run as fast / faster than other languages but you have to learn its intricacies first. A master C++ programmer will be able to wring that extra 10% out of C++ code (vs, say, Java or C#). A novice or intermediate-level C++ programmer will, more often than not, write code the performs equally or worse.

Interesting read: "Developing a Chinese/English dictionary". Rico Mariani (C#) and Raymond Chen (C++) into a friendly language performance deathmatch. Highly entertaining and huge learning value. (If you know who these people are, shame no you: Rico has worked on Visual Studio since its inception, more or less; Raymond has done the same for Windows. They are some of the most competent people in the field).

[OpenTK: C# OpenGL 4.4, OpenGL ES 3.0 and OpenAL 1.1. Now with Linux/KMS support!]
Washu
Washu

For something to call itself Java it needs to be licensed from Oracle which confirms that implementation meets the requirements.

There is no such thing in C++ or C.

While there is no such body which owns the C++ language such as Oracle does (well, it supposedly doesn't, but as long as it controls the language certification unit tests (which it isn't supposed to but does anyways, just like sun did) then this licensing will be required) the standard does dictate that a conforming non-standalone implementation of the C++ language provide the standard library (which takes up about half of the standard text).
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
Drathis
Drathis

I think the OP and the consequent answers show a very important lesson: C++ can be made to run as fast / faster than other languages but you have to learn its intricacies first.

The other lesson we learned was that buffering is important, no matter the language


way2lazy2care
way2lazy2care

[quote name='Fiddler' timestamp='1297968142' post='4775509']
I think the OP and the consequent answers show a very important lesson: C++ can be made to run as fast / faster than other languages but you have to learn its intricacies first.

The other lesson we learned was that buffering is important, no matter the language
[/quote]
Except for French because the input doesn't matter as the return is always hate.

/french burn
Fiddler
Fiddler

[quote name='Antheus' timestamp='1297883077' post='4775063']
For something to call itself Java it needs to be licensed from Oracle which confirms that implementation meets the requirements.

There is no such thing in C++ or C.

While there is no such body which owns the C++ language such as Oracle does (well, it supposedly doesn't, but as long as it controls the language certification unit tests (which it isn't supposed to but does anyways, just like sun did) then this licensing will be required) the standard does dictate that a conforming non-standalone implementation of the C++ language provide the standard library (which takes up about half of the standard text).
[/quote]

Then again, noone interprets the C++ standard in quite the same way, so this is mostly a moot point anyway.
[OpenTK: C# OpenGL 4.4, OpenGL ES 3.0 and OpenAL 1.1. Now with Linux/KMS support!]
Tachikoma
Tachikoma
I would be interested to see software image manipulations algorithm implemented in C++ and Java and see how they perform side by side. I was meant to do this for a while now, but never got around to it.
Bregma
Bregma
For the record, the Java version ran in 5.5s on my machine, and the C++ and the C99 versions both ran in 5.3s.

When stdout is redirected to /dev/null, the Java version clocks in at 0.069s, the C++ version at 0.014s, and the C99 version at 0.020. I assume the larger difference is due to the expense of the JVM startup, which is generally amortized in real world applications and is hidden by the terminal buffering in the non-redirected runs. The C++ version is slightly faster because it does not have the runtime interpreter required by printf in the tight loop, just what amounts to a [font="Courier New"]memcpy[/font].

I am using GCC 4.5.2 for C and C++ and OpenJDK 6 for Java on an Intel i5-540 (2.53 GHz 64-bit quadcore) running Ubuntu 11.04 alpha 3.
Stephen M. Webb
Professional Free Software Developer
Antheus
Antheus

For the record, the Java version ran in 5.5s on my machine, and the C++ and the C99 versions both ran in 5.3s.

When stdout is redirected to /dev/null, the Java version clocks in at 0.069s, the C++ version at 0.014s, and the C99 version at 0.020. I assume the larger difference is due to the expense of the JVM startup, which is generally amortized in real world applications and is hidden by the terminal buffering in the non-redirected runs. The C++ version is slightly faster because it does not have the runtime interpreter required by printf in the tight loop, just what amounts to a [font="Courier New"]memcpy[/font].


Java strings use char internally, which are 16-bit. The C++ version uses string, which are 8-bit. Shouldn't matter all that much, but might either require twice as much work for memcpy or perhaps even some codepage conversion when dumping to console.
Prefect
Prefect
For the original console output example, the most important question is: What terminal application received the output of those programs? In my experience, when running programs with tons of console output, the performance bottleneck is often not the program itself, but the terminal emulator. Many terminal emulators suck at processing large amounts of output.

On Linux, for example, gnome-terminal used to be notoriously slow, and only got a little better over time. Konsole has always been very fast in my experience. Similarly, some IDEs have horribly slow output window implementations.

You may have ended up benchmarking your IDE your terminal emulator instead of your program.
Widelands - laid back, free software strategy
Lord Crc
Lord Crc

There are a few mishaps that happen when beginners try to benchmark things. Often they don't turn on release mode since debug mode has a lot of checks to assist the programmer.


I'd like to point out that if you're using Visual Studio you need to run the executable without the debugger attached as well as turning on release mode, that is CTRL+F5 instead of just F5. Otherwise the results will not be representative. In my application the difference can be an order of magnitude or more.

Also what simple benchmarks like this usually fails to capture is how the language features can change the implementation of an algorithm, leading to vastly different performance characteristics compared to a "straight port". For example using list comprehension etc vs an explicit for loop in Python, or template metaprogramming in C++, like in this example. These things will matter when writing a full-blown application in that language.

Topic Locked

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

Sign in to reply to this topic.