8

Today I made a simple test to compare the speed between java and c - a simple loop that makes an integer "i" increment from 0 to two billion.

I really expected c-language to be faster than java. I was surprised of the outcome:

the time it takes in seconds for java: approx. 1.8 seconds

the time it takes in seconds for c: approx. 3.6 seconds.

I DO NOT think that java is a faster language at all, but I DO NOT either understand why the loop is twice as fast as c in my simple programs?

Did I made a crucial misstake in the program? Or is the compiler of MinGW badly configurated or something?

public class Jrand {

 public static void main (String[] args) {

    long startTime = System.currentTimeMillis();
    int i; 
    for (i = 0; i < 2000000000; i++) {
        // Do nothing!
    }
    long endTime = System.currentTimeMillis();
    float totalTime = (endTime - startTime);

    System.out.println("time: " + totalTime/1000);
 }

}

THE C-PROGRAM

#include<stdio.h>
#include<stdlib.h>
#include <time.h>
int main () {

    clock_t startTime;
    startTime = clock();

    int i;
    for (i = 0; i <= 2000000000; i++) {
        // Do nothing
    }
    clock_t endTime;
    endTime = clock();

    float totalTime = endTime - startTime;
    printf("%f", totalTime/1000);

    return 0;
}
Björn Hallström
  • 3,775
  • 9
  • 39
  • 50
  • 3
    The loop is most probably ignored in Java. Try doing something meaningful in the loop, like updating a sum and printing it after the loop. See also [this thread](http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java) – Sanjay T. Sharma Sep 16 '13 at 17:44
  • 4
    Optimizer. As Sanjay said. – Devolus Sep 16 '13 at 17:44
  • 11
    Did you turn on optimizations for the C build? I'm guessing you probably didn't because otherwise, your C code should be returning 0 seconds. – Mysticial Sep 16 '13 at 17:45
  • 1
    I would like to add a philosophical note: simple speed comparison are you usually not reliable, since they do not compensate for a multitude of different factors impacting the speed. – PM 77-1 Sep 16 '13 at 17:48
  • 5
    It's essentially never the case that Language A is faster than Language B. Program X in Language A might be faster than Program Y in Language B, though. – Louis Wasserman Sep 16 '13 at 17:48
  • 8
    "I DO NOT think that java is a faster language at all" Holding on to a dogma irrespective of the evidence. Excellent(!) – Richard Tingle Sep 16 '13 at 18:12

3 Answers3

24

Rebuild your C version with any optimization level other than -O0 (e.g. -O2) and you will find it runs in 0 seconds. So the Java version takes 1.6 seconds to do nothing, and the C version takes 0.0 seconds (really, around 0.00005 seconds) to do nothing.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 11
    Maybe on his system. On the *first run* of my old laptop (Core 2 Duo) the Java version takes 0.059 seconds... It's just the start up time of the JVM, probably disk IO. Just in case there are any Java bashers here. – Maarten Bodewes Sep 16 '13 at 18:25
  • thanks! I used -O2 and added a simple calc. inside the loop. c-language: 0.0000 ... seconds. Java: 6.7 seconds. Could the latter also be optimized? – Björn Hallström Sep 16 '13 at 19:14
  • @owlstead: 0.059 sec startup overhead is plenty reason to bash Java still. It's longer than the frametime for typical framerates/refresh-rates. – R.. GitHub STOP HELPING ICE Sep 17 '13 at 02:04
  • It's the startup time of the VM, after 3 runs it was down to 0.01. It needs to start up some threads for garbage collection in the background etc. Maybe that makes it less useful for command line applications that need a short run time, but that's about it. – Maarten Bodewes Sep 17 '13 at 07:21
  • It's also fairly problematic for programs that run once per network connection (via inetd, traditional cgi, etc.). – R.. GitHub STOP HELPING ICE Sep 18 '13 at 00:19
  • My question is why does java take 6.7 seconds to do nothing? What is it doing? – alexyorke Jan 04 '14 at 01:12
10

Java is more aggressive at eliminating code which doesn't do anything. It is less likely to assume the developer knows what they are doing. You are not timing the loop but how long it takes java to detect and eliminate the loop.

In short, Java is often faster at doing nothing useful.

Also you may find that if you optimise the C code and remove debugging information it will do the same thing, most likely shorter.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 7
    Any decent C compiler will certainly generate no code at all for the useless loop unless you intentionally compile with optimization disabled, which is a tool for single-stepping through the program and being able to understand the flow of the abstract machine. – R.. GitHub STOP HELPING ICE Sep 16 '13 at 17:48
1

If you want to benchmark this, instead of doing nothing, try to something useful like calculating something on each iterations. For e.g. count the loops in some other variable, and make sure you use it at the end (by printing it for e.g), so that it will not be optimized out.

Alternate simple tests could be accessing an array linearly (reading only), copying elements from one array to another (read+write), or doing some operations on the data. Some of these cases might be interesting as they open several very simple compiler optimizations that you can later see in the result binary/bytecode, such as loop unrolling, register allocation, and maybe even more complicated stuff like vectorization or code motion. Java on the other may employ some nastier tricks such as jitting (dynamically recompiling on the fly)

The scope of compiler optimization is huge, you've just encountered the most basic one - eliminating useless code :)

Leeor
  • 19,260
  • 5
  • 56
  • 87