I have a Java program where I'm trying new algorithms for square rooting and comparing them to the native Math.sqrt(a)
method in Java. What I find weird is that the first time the .sqrt(a)
method is called in the program, it takes at least 50,000ns whereas the times after, it only takes a few thousand. Does this have to do with how the system time is being calculated during the first few moments of running the program, or are the methods actually executing slower for some reason?

- 998
- 1
- 9
- 17
-
1Almost certainly class loading. Try running with `-verbose:class -verbose:jni -verbose:gc -XX:+PrintCompilation` and take a look at what is causing the time. – sprinter Apr 19 '17 at 01:53
1 Answers
There are significant overheads in starting a Java application.
- The JVM (the
java
executable) needs to be loaded. - The JVM needs to bootstrap:
- creating and initializing the heap
- classloading various system classes
- and so on
- Your classes need to be classloaded. This typically triggers further classloading of system classes, third party libraries and so on.
- After a bit ... the JIT compiler starts to compile methods to native code.
- While this is happening, the GC may run to clean up garbage that was created by JIT compilation and classloading.
All of this adds up to significant startup costs ... compared to (say) an application that is implemented in C or C++, compiled and linked to an executable.
However, this should bot be relevant to developing and benchmarking algorithms in Java. You simply need to do the benchmarking in a way that eliminates the "JVM warmup" overheads. For more details:
@user7859067 comments:
need very awesome performance, go native.
I assume you mean ... implement the code as a Java native method. That doesn't help with JVM bootstrap overheads. And "going native" isn't always a win, since there are overheads when calling into custom native method from Java.
However, it is a fact that the implementations of many Math
functions are in native code ... for speed. (The JIT compiler has tweaks to generate special fast calls to "intrinsic" native methods, but (AFAIK) you can't use this yourself without modifying the JRE codebase ...) Anyhow, if you compare your (pure Java) implementation's performance against the standard (native) Math.sqrt
method, you are comparing apples and oranges.
-
I think 7859067 was just having a rant, and meant "don't use Java at all", rather than "use a native method from Java". – Dawood ibn Kareem Apr 19 '17 at 02:59
-
Maybe. However, he raised an important point, and I'm giving a "straight" answer to that point, – Stephen C Apr 19 '17 at 03:16