Daniel Pitts’ Tech Blog

Please vote no on 8.
Please vote no on 8.

Why is C so slow? Java vs. C benchmark.

Daniel, December 8th, 2007

Recently I’ve seen a few attacks on Java’s performance on comp.lang.java.programmer. So, I’ve decided to write my own benchmarks and test it myself. I expected the C version to perform slightly better, but at least in the same range, as the Java version. I was surprised that the Java version performed better, on both the client vm and the server vm.

I did my own benchmarks using these files:

bench.c

#include <stdio.h>
#include <time.h>

void bench() {
  long foo = 0;
  clock_t start = clock();
  for (long i = 1; i < 5000; ++i) {
    for (long j = 1; j < i; ++j) {
      if ((i % j) == 0) {
        foo ++;
      }
    }
  }
  clock_t end = clock();
  printf("%d %dms\n", foo,
     (int) ((end - start) * 1000 / CLOCKS_PER_SEC));
}

int main() {
  for (long i = 1; i < 10; ++i) {
    printf("%d: ", i);
    bench();
  }
}

Bench.java

public class Bench {
  static final long CLOCKS_PER_SEC = 1000;
  static void bench() {
    int foo = 0;
    long start = System.currentTimeMillis();
    for (int i = 1; i < 5000; ++i) {
      for (int j = 1; j < i; ++j) {
        if ((i % j) == 0) {
          foo ++;
        }
      }
    }
    long end = System.currentTimeMillis();
    System.out.printf("%d %dms\n", foo,
       (int) ((end - start) * 1000 / CLOCKS_PER_SEC));
  }

  public static void main(String[] args) {
    for (int i = 1; i < 10; ++i) {
      System.out.printf("%d: ", i);
      bench();
    }
  }
}

Then I ran these:

-bash-3.00$ java -version
java version "1.5.0_09"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03)
Java HotSpot(TM) Client VM (build 1.5.0_09-b03, mixed mode, sharing)
-bash-3.00$ javac Bench.java
-bash-3.00$ g++ --version
g++ (GCC) 3.3.3 (NetBSD nb3 20040520)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-bash-3.00$ g++ bench.c -o bench

Now I’m ready to run the individual tests:

-bash-3.00$ java -server Bench
1: 38357 457ms
2: 38357 416ms
3: 38357 401ms
4: 38357 394ms
5: 38357 394ms
6: 38357 401ms
7: 38357 395ms
8: 38357 401ms
9: 38357 394ms
-bash-3.00$ java -client Bench
1: 38357 421ms
2: 38357 400ms
3: 38357 394ms
4: 38357 400ms
5: 38357 393ms
6: 38357 393ms
7: 38357 400ms
8: 38357 394ms
9: 38357 401ms
-bash-3.00$ ./bench
1: 38357 450ms
2: 38357 440ms
3: 38357 450ms
4: 38357 430ms
5: 38357 450ms
6: 38357 440ms
7: 38357 450ms
8: 38357 440ms
9: 38357 450ms

As you can see, the Java version is approximately 10% faster than the c version. So, here is my challenge. Why is C so slow? I thought it was supposed to be faster than Java.

Tags: , , , ,

6 Responses to “Why is C so slow? Java vs. C benchmark.”

  1. Aviad Ben Dov Says:

    Try to see if the compilation could be better optimized. Remember that the JVM enjoys the added benefit of being able to (sometimes) compile the bytecode (using JIT) to a more localized assembly code, unlike GCC which usually compiles for the (reasonably) lowest common denominator to allow binary portability between different computers (for example, allowing the binary you compiled to still execute on a Pentium 3 machine).

  2. Daniel Says:

    I was doing a base example just to counteract the common myth that “C is always faster than Java.” The truth of the matter is that no micro-benchmark will capture all cases. The important thing to point out is that Java programs will benefit from the latest VM, where a C program would have to be recompiled to enjoy optimization for a particular platform.

  3. Aviad Ben Dov Says:

    I just noticed something, not that it should matter [much]: In the C version you used “long” for the loops and in the Java version you used “int”. Do you get different results when you change these?

  4. Daniel Says:

    In c, long is 32 bit, in Java, int is 32 bit. That’s why the difference.
    If I use 64 bit (long) in Java, I get slightly different results.

  5. ahmet Says:

    try with java 1.6 update 4. you will possibly get better results with Java. Still, just looping is not really a good benchmark.

  6. Daniel Says:

    @ahmet
    I know its not a good benchmark. This post was actually a little tongue-in-cheek. People frequently benchmark C/C++ vs Java in just this manor in order to defame Java. I used the same invalid benchmark, and found that the results were actually reversed on my system.

Leave a Reply