Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible increase of performance using JNI?

A year or two ago I created a program written in Java to simulate the n-body problem. Recently I've gotten the crazy idé to rewrite the program as a distributed program to be able to simulate larger masses with better accuracy.

Profiling the old program showed, as expected, that roughly 90% of the program was spent calculating float type values. If I remember correctly C/C++ is ALOT faster then Java at doing arithmetics operations, especially float type calculations.

Anyways, here's the actual question :)

By using JNI, can I expect an increase in speed equal to a program written in C/C++ (for the calculations) or will the JVM slow it down?

like image 896
David Avatar asked Dec 09 '22 09:12

David


1 Answers

Most float operations take around 1 ns in Java, so I am not sure how much faster you would expect them to be in C++.

However JNI calls often take around 30 ns, so unless you are performing alot of floating point operations per call, you will cost more than you save.

As the following micro-benchmark suggests, once the code as warmed up, each operations is sub nano second.

If you want this to go faster, you could use multiple cores and make it 4x or more faster.

public static void main(String[] args) throws Exception {
    int length = 200000;
    double[] a = fill(new double[length]);
    double[] b = fill(new double[length]);
    double[] c = fill(new double[length]);
    double[] x = new double[length];

    for (int i = 0; i < 10; i++)
        testTime(length, a, b, c, x);
}

private static void testTime(int length, double[] a, double[] b, double[] c, double[] x) {
    long start = System.nanoTime();
    for (int i = 0; i < length; i++)
        x[i] = a[i] * b[i] + c[i];
    long time = System.nanoTime() - start;
    System.out.printf("Average time per double operation was %.1f ns%n", time / 2.0 / length);
}

private static double[] fill(double[] doubles) {
    for (int i = 0; i < doubles.length; i++)
        doubles[i] =  Math.random();
    return doubles;
}

prints

Average time per double operation was 10.9 ns
Average time per double operation was 17.9 ns
Average time per double operation was 1.7 ns
Average time per double operation was 1.0 ns
Average time per double operation was 0.9 ns
Average time per double operation was 0.8 ns
Average time per double operation was 0.9 ns
Average time per double operation was 0.8 ns
Average time per double operation was 1.0 ns
Average time per double operation was 0.9 ns
like image 140
Peter Lawrey Avatar answered Dec 13 '22 23:12

Peter Lawrey