BACKGROUND
Assume I have a direct ByteBuffer:
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
and assume I am passing the buffer to an AsynchronousSocketChannel to read chunks of data off that socket up to X bytes at a time (1024 in the example here).
The transfer time off the socket into the direct ByteBuffer is fantastic because it is all occurring in native OS memory space; I haven't passed through the JVM "blood-brain" barrier yet...
QUESTION
Assuming my job is to scan through all the bytes read back in from the direct byte buffer, what is the fastest way for me to do this?
I originally asked "... utilizing sun.misc.Unsafe" but maybe that is the wrong assumption.
POSSIBLE APPROACHES
I currently see three approaches and the one I am most curious about is #3:
It does occur to me that assuming the copyMemory operation does exactly what it advertises, even in the more-optimal OS space, that the #2 approach above is probably still the most optimized since I am not creating duplicates of the buffer before beginning to process it.
This IS different than the "can I use Unsafe to iterate over a byte[] faster?" question as I am not even planning on pulling the bytes into a byte[] internally if it isn't necessary.
Thanks for the time; just curious if anyone (Peter?) has gotten nuts with Unsafe to do something like this.
In order to get the byte array from ByteBuffer just call the ByteBuffer. array() method. This method will return the backed array. Now you can call the String constructor which accepts a byte array and character encoding to create String.
A direct buffer is a chunk of native memory shared with Java from which you can perform a direct read. An instance of DirectByteBuffer can be created using the ByteBuffer. allocateDirect() factory method.
wrap. Wraps a byte array into a buffer. The new buffer will be backed by the given byte array; that is, modifications to the buffer will cause the array to be modified and vice versa. The new buffer's capacity will be array.
ByteBuffer
methods are extremely fast, because these methods are intrinsics, VM has mapped them to very low level instructions. Compare these two approaches:
byte[] bytes = new byte[N];
for(int m=0; m<M; m++)
for(int i=0; i<bytes.length; i++)
sum += bytes[i];
ByteBuffer bb = ByteBuffer.allocateDirect(N);
for(int m=0; m<M; m++)
for(int i=0; i<bb.remaining(); i++)
sum += bb.get(i);
on my machine, the difference is 0.67ns vs 0.81ns (per loop).
I'm a little surprised that ByteBuffer is not as fast as byte[]. But I think you should definitely NOT copy it to a byte[] then access.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With