So… I always wondered, whether Java’s Math.sqrt() would be faster than a call to the JNI, calling <math.h>'s/C’s sqrt().
If anyone else wondered, here is the result, printed by my program:
The Java code is the following (REALLY trivial):
package org.matheusdev.jni;
import java.util.Random;
public class SQRTNative {
static {
System.loadLibrary("SQRTNative");
}
private native static double sqrt(double d);
public static void main(String[] args) {
final long repeat = 2330000000L; // 2.330.000.000 times sqrt().
final int values = 1000000; // 1.000.000 a.k.a. 4 MB of doubles.
long time; // local for measuring time.
// Initialize random values:
System.out.println("Starting to initialize values.");
double[] vals = new double[values];
Random rand = new Random();
for (int i = 0; i < values; i++) {
vals[i] = rand.nextDouble()*1000;
}
// Java's Math.sqrt:
System.out.println("Initializing finished. Starting Java's Math.sqrt():");
time = System.currentTimeMillis();
for (long i = 0; i < repeat; i++) {
Math.sqrt(vals[(int)(i%values)]);
}
System.out.println("Time taken with Math.sqrt(): " + (System.currentTimeMillis()-time));
// Native sqrt() from C++:
System.out.println("Starting native C++'s sqrt():");
time = System.currentTimeMillis();
for (long i = 0; i < repeat; i++) {
sqrt(vals[(int)(i%values)]);
}
System.out.println("Time taken with native sqrt(): " + (System.currentTimeMillis()-time));
}
}
And the code inside the “libSQRTNative.so” (running linux 64 bit here ) is simple too:
#include "jni.h"
#include <math.h>
#include "SQRTNative.h"
JNIEXPORT jdouble JNICALL
Java_org_matheusdev_jni_SQRTNative_sqrt(JNIEnv *env, jclass cls, jdouble d)
{
return sqrt(d);
}
Built with “QtCreator’s build lib for release”, aka GCC. Haven’t messed around with any build flags
One thing more to add: I use “only” 1 MIO values, cause I can’t even create an Array of the size of 2.330.000.000 doubles, and besides, it would crash with an OutOfMemoryException anyways.
I used exactly 2.330.000.000, cause I have a running 2.33 GHz cpu at that point, so you can easily see, that Java’s sqrt takes about 8-9 clock ticks per computation, and the C++'s one takes aabout 77 cpu clock ticks.
These values are not perfect, because of the system needing resources, the Chromium running with 13 Tabs, the Eclipse running, one Dolphin running and a QtCreator running.
I assume that most time spent in the native version is the JNI overhead.
Also, this was a JNI-learing-and-have-fun-with-performance-tests-test-project, keep that in mind, and correct me, if I could do something better