-
-
Notifications
You must be signed in to change notification settings - Fork 53
Open
Description
Current ISequentialOutStream
interface wrapper has some inefficiency because it does not re-use allocated byte array.
From CPPToJavaSequentialOutStream.cpp
:
jbyteArray dataArray = jniEnvInstance->NewByteArray(size); // New large byte array allocation
jniEnvInstance->SetByteArrayRegion(dataArray, 0, (jsize) size, (const jbyte*) data); // Fill it with data
// public int write(byte[] data);
jint result = _iSequentialOutStream->write(jniEnvInstance, _javaImplementation, dataArray); // Pass data to Java code (ISequentialOutStream#write(byte[] data))
if (jniEnvInstance.exceptionCheck()) {
jniEnvInstance->DeleteLocalRef(dataArray); // Dispose array
return S_FALSE;
}
jniEnvInstance->DeleteLocalRef(dataArray); // Dispose array
Source:
jbyteArray dataArray = jniEnvInstance->NewByteArray(size); | |
jniEnvInstance->SetByteArrayRegion(dataArray, 0, (jsize) size, (const jbyte*) data); | |
// public int write(byte[] data); | |
jint result = _iSequentialOutStream->write(jniEnvInstance, _javaImplementation, dataArray); | |
if (jniEnvInstance.exceptionCheck()) { | |
jniEnvInstance->DeleteLocalRef(dataArray); | |
return S_FALSE; | |
} | |
jniEnvInstance->DeleteLocalRef(dataArray); |
Problem here that allocation of a large array is relatively costly operation and has some additional performance drawbacks (causes CPU cache thrashing and adds some extra Java GC pressure.
Suggestion:
- Change Java interface
ISequentialOutStream#write(byte[] data)
toISequentialOutStream#write(byte[] data, int offset, int length)
(offset field is not really necessary through, as it always going to be 0). - Instead of immediate array disposal, keep it ("cache") for re-use.
- Instead of new array allocation check if existing array has enough capacity for
size
bytes. If not, dispose existing array and allocate new, big enough for the new data chunk. - Dispose the "cached" array when extraction process completes
Metadata
Metadata
Assignees
Labels
No labels