Advertisement

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

Started by February 16, 2011 06:51 PM
17 comments, last by Lord Crc 13 years, 6 months ago
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?
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.
Advertisement
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. :(
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

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 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
Advertisement
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...


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.

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() - 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++.
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!]

This topic is closed to new replies.

Advertisement