3

I have made a simple loop in Java just to test the speed. Compared to the same loop in C it takes a lot more time. 2 billion iterations takes about 6.5 seconds when its executed

If its considered to be slow - what could one do to improve the performance?

Could one blame the startup of the JVM? Or - is the JIT-compiler not doing its job?

  • platform: windows xp
  • processor speed: 3.4 GHz

    public class Jrand {
    
    public static void main (String[] args) {
    
      float f;
    
      long startTime = System.currentTimeMillis();
    
      for (int i = 0; i < 2000000000; i++) {
        f = i * 0.0001F;
      }
      long endTime = System.currentTimeMillis();
      float totalTime = (endTime - startTime);
      System.out.println("time: " + totalTime/1000);
      }
    }
    
Maroun
  • 94,125
  • 30
  • 188
  • 241
Björn Hallström
  • 3,775
  • 9
  • 39
  • 50

5 Answers5

6

Startup time

Java startup time is often much slower than many languages, including C, C++, Perl or Python, because a lot of classes (and first of all classes from the platform Class libraries) must be loaded before being used.

So this could be one reason

But also i think that Java tends to be slower than native language in every aspect. Take a look at these statistics: enter image description here

And a graph: enter image description here

Can you make it faster? no - and probably you could blame JVM for it ;)

Maciej Cygan
  • 5,351
  • 5
  • 38
  • 72
  • 1
    "*Java tends to be slower than native language in every aspect.*" => huh no. Your example is biased and only shows one aspect (pure calculation stuff). – assylias Sep 17 '13 at 16:23
6

This

for (int j = 0; j < 10; j++) {
    float f;

    long start = System.nanoTime();

    for (int i = 0; i < 2000000000; i++) {
        f = i * 0.0001F;
    }
    long end = System.nanoTime();
    long timeToCallNanoTime = System.nanoTime() - end;
    long time = Math.max(0, end - start - timeToCallNanoTime);
    System.out.println("time: " + time + " ns.");
}

prints

time: 2580790 ns.
time: 4241443 ns.
time: 17 ns.
time: 0 ns.
time: 0 ns.
time: 0 ns.
time: 0 ns.
time: 0 ns.
time: 5 ns.
time: 0 ns.

As you can see the JIT has optimised the loop away completely. It can't get faster than that.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
2

I tried with this example :

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

int main(void) {

  clock_t start,finish;
  double duration;

  float f = 0;
  long i;

  start = clock();
  for(i=0;i<2000000000;i++) {
    f=i*0.0001;
  }
  finish = clock();
  duration = (double) (finish - start);

  printf ("Total duration : %f", duration/CLOCKS_PER_SEC );

}

With gcc -O main.c, this program takes 540ms to execute.

With gcc -O2 main.c, the output is Total duration : 0.000000 (< 1 μs): It seems that with O2, the loop is not executed.

In Java, your program takes 4ms to execute on my computer (standard computer, nothing huge).

6.5s on your side is far too long. You seem to have serious problem (or you read 6.5s instead of 6.5ms).

So this is just a matter of compiler optimization.

Arnaud Denoyelle
  • 29,980
  • 16
  • 92
  • 148
  • +1 4 ms is likely to be the time it takes to detect the code is pointless and optimise it away. If you time it more than once in a loop, you should see it drop to < 1 micro-second. – Peter Lawrey Sep 17 '13 at 12:12
1

I do not think is it JVM startup or JIT compilation time since your start time is after the jvm is up and the class is compiled.

Itay Karo
  • 17,924
  • 4
  • 40
  • 58
1

what could one do to improve the performance?

Well, that would depend on what the loop was actually doing (if it was doing something useful.) In real life situations, the JIT is usually very good at finding and optimising hotspots in code, it's much less so for contrived examples like this (which is what makes them bad benchmarks.)

In this example you're just manipulating a float and it's always going to be the same value at the end - so in a real life scenario I'd say speed it up by removing the loop and just initialising it to its final value there and then!

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
  • Hotspot won't do anything here as everything happens in a single method, the method as a whole has to be executed several times before hotspot kicks in. – Mark Rotteveel Sep 17 '13 at 11:36
  • A smart compiler would replace the loop with `f = (2000000000-1) * 0.0001F`- which I guess is what the C compiler did. The hotspot can remove loops on the fly (escape analysis), even if the method is just called once- this doesn't apply here, because the loop escapes its context by setting `f`. – Thomas Jungblut Sep 17 '13 at 11:42
  • 1
    @MarkRotteveel There is also On-Stack Replacement, which would allow it to be JIT-ed in the middle of iteration. – Marko Topolnik Sep 17 '13 at 12:05