Production-ready comparison between byte-array and ByteBuffer I want to compare the performance difference between using byte[] and ByteBuffer in Java, which approach I should use in my production code. I wrote the following Java sandbox code:

public native int MD_GetHsmInfo(int hsmIndex, int infoType, byte[] value);
public native int MD_TestByteBuffer(int hsmIndex, int infoType, ByteBuffer buf);

//inside main()
byte[] arr = new byte[64];
h.MD_GetHsmInfo(2, 0, arr);
System.out.println("&gt;" + new String(arr) + "&lt;");

ByteBuffer buf = ByteBuffer.allocateDirect(64);
h.MD_TestByteBuffer(2, 1, buf);
System.out.println("&gt;" + StandardCharsets.UTF_8.decode(buf).toString() + "&lt;");


And then I have my C code - this is the one I need help with:

JNIEXPORT jint JNICALL Java_com_sprint_jni_JNISandbox_MD_1GetHsmInfo
    (JNIEnv *env, jobject obj, jint hsmIndex, jint infoType, jbyteArray array)
{
    //printf("This is MD_GetHsmInfo()\n");
    jboolean isCopy;
    jsize len = (*env)-&gt;GetArrayLength(env, array);
    jbyte* bp = (*env)-&gt;GetByteArrayElements(env, array, &amp;isCopy);
    if (!bp) {
        // exception handling here
        return 0;
    }

    jint ret = MD_GetHsmInfo(hsmIndex, infoType, bp, len);
    int mode = 0;
    // if error code is returned then do not save changes
    if(ret != 0) {
        mode = JNI_ABORT;
    }
    (*env)-&gt;ReleaseByteArrayElements(env, array, bp, mode);

    return ret;
}

JNIEXPORT jint JNICALL Java_com_sprint_jni_JNISandbox_MD_1TestByteBuffer
    (JNIEnv *env, jobject obj, jint hsmIndex, jint infoType, jobject buf)
{
    jbyte *bp = (*env)-&gt;GetDirectBufferAddress(env, buf);
    jint len = (*env)-&gt;GetDirectBufferCapacity(env, buf);
    //printf("length of buffer = %d", len);
    jint ret = MD_GetHsmInfo(hsmIndex, infoType, bp, len);
    return ret;
}


Both functions seem to work fine, but I would like to make both functions production-ready, so that I can demonstrate without bias which approach to use. As I am not too familiar with JNI, it is likely that my code is not written optimally, so I would appreciate any feedback on that too.



Background

In the above snippet, MD_GetHsmInfo is a C function which my Java code needs to call.

MD_RV MD_GetHsmInfo(uint32_t hsmIndex, MD_Info_t infoType, void *pValue, uint32_t valueLen);


pValue is described as such:


  The address of the buffer to hold the information value. The buffer
  must have been allocated by the caller. The size of the buffer is
  determined by the infoType that is being obtained.


MD_RV and MD_Info_t are enums defined as follows:

typedef enum {
    MDI_HSM_DESCRIPTION = 1,
    //...so on
} MD_Info_t;

// similar implementation for MD_RV


The actual implementation of the function resides within a DLL file, but I do not have access to it yet. For now I have written a dummy implementation as follows:

int MD_GetHsmInfo(int hsmIndex, int infoType, void *pValue, int valueLen) {
    //printf("This is dummy implementation of MD_GetHsmInfo()\n");
    char *str;
    if(infoType == 1) {
        str = "info = 1";
    } else if(infoType == 2) {
        str = "info = 2";
    } else {
        str = "no info";
    }

    jbyte *jb = (jbyte*)pValue;
    while(*str) {
        *jb++ = *str++;
    }
    *jb = 0;
    valueLen = strlen(str);

    return 0;
}
Minor issues in MD_GetHsmInfo()

valueLen = strlen(str); serves no purpose below as the value assigned to valueLen is not used.

int MD_GetHsmInfo(int hsmIndex, int infoType, void *pValue, int valueLen) {
    ...
    valueLen = strlen(str);
    return 0;
}


Perhaps

int MD_GetHsmInfo(int hsmIndex, int infoType, void *pValue, int *valueLen) {
    ...
    *valueLen = strlen(str);
    return 0;
}


or

int MD_GetHsmInfo(int hsmIndex, int infoType, void *pValue, size_t *valueLen) {




Cast not needed

int MD_GetHsmInfo(int hsmIndex, int infoType, void *pValue, int valueLen) {
  ...
  // jbyte *jb = (jbyte*)pValue;
  jbyte *jb = pValue;