0

Hello guys I've started learning Java and I've heard something about it's slowness. For an experiment I wrote two programms in C++ and Java which seem to be equal

import java.util.*;

class Java {
  public static void main(String args[]) {
    long beg = System.currentTimeMillis();
    for (int i = 0; i < 200000000; ++i) { }
    long end = System.currentTimeMillis();
    System.out.println(end - beg);
  }
}

outputs 334

#include <cstdio>
#include <ctime>

int main() {
      double beg = clock();
      for (int i = 0; i < 200000000; ++i) { }
      double end = clock();
      printf("%f\n", (end - beg) / double(CLOCKS_PER_SEC) / 1000.0);
      return 0;
}

outputs 0.000810

I am a little confused. Is Java really that slow or I'm doing something wrong?

aioobe
  • 413,195
  • 112
  • 811
  • 826
OneMoreVladimir
  • 1,653
  • 3
  • 21
  • 32
  • 2
    Your second program is not really a C++ program, but rather a C program. – Björn Pollex May 23 '11 at 19:20
  • In many ways the JIT compiler makes Java faster. It all depends on what you're doing though. Your test is hardly conclusive and doesn't suggest that Java is 4 orders 6 orders of magnitude slower. – gshauger May 23 '11 at 19:21
  • 7
    You are not doing anything in the loop, so it can be optimized away (skipped) by the compiler. – Jonas May 23 '11 at 19:21
  • There a good discussion on the relative performance of C++ vs Java [here](http://stackoverflow.com/questions/145110/c-performance-vs-java-c) – highlycaffeinated May 23 '11 at 19:21
  • @Space_C0wb0y: Orly? I never saw header files called `` and `` in C. ;-) – C. K. Young May 23 '11 at 19:22
  • 1
    It looks like you mean 'performance' rather than 'productivity' here - higher level languages tout increased productivity (sometimes at some performance expense). – SteveMc May 23 '11 at 19:23
  • @Chris: *blush* - still, it's not very C++y.... – Björn Pollex May 23 '11 at 19:24
  • 4
    In the C program, if you're converting the result to millisecond, you should multiply by 1000, not divide by 1000. And the result should be 810 – Kien Truong May 23 '11 at 19:24
  • You might find this article about JVM OSR interesting: http://java.sun.com/developer/technicalArticles/Networking/HotSpot/onstack.html – Binil Thomas May 23 '11 at 19:27
  • @Dikei: I posted that same thought as an answer, but I promise I thought of it without reading your comment. Post your own answer, and I will delete mine and upvote yours. – Björn Pollex May 23 '11 at 19:34
  • @Space_C0wb0y: That's not necessary :) – Kien Truong May 23 '11 at 19:40
  • 2
    Besides what @Dikei and @Space say, you're likely benchmarking a ___debug version___ (which is about the first hurdle every newbie painfully runs into when trying to do benchmarks). Any decent C++ compiler would see that the loop does nothing and optimize it into nothingness in a release build. So if you got any time spent in the loop at all on the C++ side, you're likely not measuring a release build. – sbi May 23 '11 at 19:52

5 Answers5

5

You can't micro benchmark programming languages like this.

There are thousands of factors that comes into play. Keep in mind for instance that Java programs run in a virtual machine with takes some time to start up.

Some benchmarks will tell you that C++ is faster, others will say the opposite. It really boils down to what the benchmark does. Google for java c++ benchmarks and you'll find plenty of both sorts.

Modern JIT compilers can do most optimizations that any C++ compiler can do, thus for pure number crunching algorithms they have similar performance figures.

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • Thanks. Now clear. But still I'm whondered how many times aproximately Java is slower? =) – OneMoreVladimir May 23 '11 at 19:21
  • That depends completely on the application. If you for instance have lots of arrays being copied back and forth, Java can even turn out to be faster due to the fact that you can't have overlapping arrays (which allows for the compiler to optimize the code better). – aioobe May 23 '11 at 19:24
  • 1
    @OneMore: That has nothing with the productivity to do, but performance. – Jonas May 23 '11 at 19:24
  • 2
    @aioobe: There are thousand of factors, sure - but in this case there is also a factor of thousand. Squared. – Björn Pollex May 23 '11 at 19:35
  • 1
    You cannot benchmark programming languages at all. You can benchmark a programming language implementation, and then, synthetic benchmarking is nigh useless for any practical purposes. – Cat Plus Plus May 23 '11 at 20:07
3

First of all, what you're trying to do is probably pointless. Despite some similarities, there are (at least in my experience) few situations in which performance differences between C++ and Java mean much.

If you insist on trying to do it anyway, your code needs quite a bit of work to produce results that represent something accurately, even though that accurate result probably means nothing. I'd write the C++ version something like this:

#include <iostream>
#include <ctime>

int main() {
    unsigned value = 0;
    static const int loops = 200000000;
    static const double nano_factor = 1e9;

    clock_t beg = std::clock();
    for (int i=0; i<loops; ++i)
        value += i;
    clock_t end = std::clock();

    std::cout << "Ignore: " << value << "\n";
    std::cout << (((end - beg) / double(CLOCKS_PER_SEC)) / loops) * nano_factor 
              << " nanoseconds/iteration";
    return 0;
}

This does something inside the loop (though it's still pretty trivial), computing a result that I doubt most compilers can/will figure out at compile time. It then prints that out, so there's at least a high probability that the loop will actually execute.

Other than that, I believe I've fixed the timing code so the result it produces at least has something to do with reality.

I'll leave a rewrite of the Java version to somebody else, but while it doesn't need quite as much work quite as badly, it still needs some of the same before its result really has much to do with anything either.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
2

You're doing something wrong.

C++ compilers are smart enough to optimise your loop out, if it does nothing. Actually, a decent JVM (try using java -server) will do that too. ;-)

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
2

So, I will take a guess and say that your benchmark is wrong. I say it should be:

printf("%f\n", ((end - beg) * 1000.0) / double(CLOCKS_PER_SEC));
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
0

The great time for C++ is caused probably by the fact, that the empty loop is completly optimized away by the compiler.

Juraj Blaho
  • 13,301
  • 7
  • 50
  • 96