While investigating NIO DirectByteBuffer performance in our Java 2D codebase (see
6273431), I discovered some weirdness about the "empirically determined"
Bits.JNI_COPY_FROM/TO_ARRAY_THRESHOLD constants. Those values are currently set
at 6. The Direct<Type>Buffer classes currently use these values to determine
when the benefit from doing a bulk memcpy() operation outweigh the costs of the
JNI downcall. Those generated classes have code like:
public LongBuffer put(long[] src, int offset, int length) {
if ((length << 3) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
// use JNI downcall
} else {
// do int-by-int copy
...
This approach makes sense, except I think there's a miscommunication somewhere
about the units for the THRESHOLD constants. The code in the Direct<Type>Buffer
classes seems to think the THRESHOLD constants are specified in bytes, but
that would imply (for the example above) that we would use the JNI downcall path
only if ((length << 3) > 6), which of course will always be the case for 8-byte
values such as long and double. Perhaps the THRESHOLD constants were determined
in units of "elements" rather than "bytes"?
When I did some experiments, I found that a good value for the THRESHOLD constants
would be something like 28 elements. In other words, if the array to be
copied has more than 28 elements (regardless of data type), then performance
is greatly improved for the bulk get/put operations. In some quick experiments
I found that appropriate use of the THRESHOLD constants could improve performance
by 3-4x depending on the platform.
###@###.### 2005-05-29 23:04:03 GMT
I've been bitten by this performance bug for the second time; see 6347575
for the gory details. The issue is the same as I reported originally: the
THRESHOLD constants are defined too low, so doing a bulk get/put operation
with a small array can be significantly slower (up to 3x slower) than doing
a series of get() or put() calls. If the THRESHOLD constants were sized
appropriately, then this performance discrepancy would not exist. For now,
I've had to workaround this bug in my fix for 6347575 (again, read that
evaluation for more information).
6273431), I discovered some weirdness about the "empirically determined"
Bits.JNI_COPY_FROM/TO_ARRAY_THRESHOLD constants. Those values are currently set
at 6. The Direct<Type>Buffer classes currently use these values to determine
when the benefit from doing a bulk memcpy() operation outweigh the costs of the
JNI downcall. Those generated classes have code like:
public LongBuffer put(long[] src, int offset, int length) {
if ((length << 3) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
// use JNI downcall
} else {
// do int-by-int copy
...
This approach makes sense, except I think there's a miscommunication somewhere
about the units for the THRESHOLD constants. The code in the Direct<Type>Buffer
classes seems to think the THRESHOLD constants are specified in bytes, but
that would imply (for the example above) that we would use the JNI downcall path
only if ((length << 3) > 6), which of course will always be the case for 8-byte
values such as long and double. Perhaps the THRESHOLD constants were determined
in units of "elements" rather than "bytes"?
When I did some experiments, I found that a good value for the THRESHOLD constants
would be something like 28 elements. In other words, if the array to be
copied has more than 28 elements (regardless of data type), then performance
is greatly improved for the bulk get/put operations. In some quick experiments
I found that appropriate use of the THRESHOLD constants could improve performance
by 3-4x depending on the platform.
###@###.### 2005-05-29 23:04:03 GMT
I've been bitten by this performance bug for the second time; see 6347575
for the gory details. The issue is the same as I reported originally: the
THRESHOLD constants are defined too low, so doing a bulk get/put operation
with a small array can be significantly slower (up to 3x slower) than doing
a series of get() or put() calls. If the THRESHOLD constants were sized
appropriately, then this performance discrepancy would not exist. For now,
I've had to workaround this bug in my fix for 6347575 (again, read that
evaluation for more information).
- relates to
-
JDK-6509032 (bf) Monomorphic implementations for Direct and Heap versions of X-Buffer
-
- Open
-
-
JDK-6273431 OGL: improve performance of parameter queuing
-
- Resolved
-
-
JDK-6347575 FileImageInputStream.readInt() and similar methods are inefficient
-
- Resolved
-