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(">" + new String(arr) + "<");
ByteBuffer buf = ByteBuffer.allocateDirect(64);
h.MD_TestByteBuffer(2, 1, buf);
System.out.println(">" + StandardCharsets.UTF_8.decode(buf).toString() + "<");
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)->GetArrayLength(env, array);
jbyte* bp = (*env)->GetByteArrayElements(env, array, &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)->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)->GetDirectBufferAddress(env, buf);
jint len = (*env)->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;
}