Ivaylo Toskov
Ivaylo Toskov

Reputation: 4021

JNI: Is GetIntArrayElements always linear in time?

Since I want to know whether it is worth it to use JNI to improve the performance of my application, I wanted to know what the complexity of GetIntArrayElements is. Does it always allocate a new primitive array in C and copy all the elements from the original Java array, or it somehow manages to pass a pointer?

I want to find out if it's worth it to use JNI for algorithms that are linear, e.g. pointwise multiplication of two vectors. In case GetIntArrayElements is linear, I guess the potential performance boost from using C/C++ would be lost if we need to copy the vectors first.

Upvotes: 1

Views: 517

Answers (1)

Jorn Vernee
Jorn Vernee

Reputation: 33875

GetIntArrayElements has an optional by-reference parameter called isCopy. When the VM makes a copy of the data for you to use, this parameter will be set to JNI_TRUE. The idea is that different VM implementations might have different memory representations of an array, also one that is not compatible with the memory layout that C expects.

Usually the fastest way of sharing memory between Java and native code is by using direct ByteBuffers (ones that are created with allocateDirect). These buffers use an underlying block of memory that is directly usable from C/C++.

In Java you create a buffer and fill it with some data:

public static void main(String[] args) {
    byte[] ba = "Hello Wolrd!".getBytes(StandardCharsets.US_ASCII);
    ByteBuffer bb = ByteBuffer.allocateDirect(ba.length + 1); // for terminator
    bb.put(ba);
    callCPP(bb);
}

private static native void callCPP(ByteBuffer bytes);

And then from C/C++ you can get the address of the underlying block of bytes with GetDirectBufferAddress (this is in C++):

JNIEXPORT void JNICALL Java_Main_callCPP(JNIEnv *env, jclass, jobject buff) {
    const char* str = (char*) env->GetDirectBufferAddress(buff);
    printf(str); // Hello World!
}

The downside of using a ByteBuffer is that there is no data abstraction, like a class' field has a specific type, a position in the byte buffer does not.

Upvotes: 1

Related Questions