When to use Array, Buffer or direct Buffer When to use Array, Buffer or direct Buffer arrays arrays

When to use Array, Buffer or direct Buffer


Direct buffers are not meant to accelerate access from Java code. (If that were possible there was something wrong with the JVM’s own array implementation.)

These byte buffers are for interfacing with other components as you can write a byte buffer to a ByteChannel and you can use direct buffers in conjunction with native code such as with the OpenGL libraries you mentioned. It’s intended to accelerate these operation then. Using a graphics card’s chip for rendering can accelerate the overall operation to a degree more than compensating the possibly slower access to the buffer from Java code.

By the way, if you measure the access speed to a byte buffer, especially the direct byte buffers, it’s worth changing the byte order to the native byte order before acquiring a FloatBuffer view:

FloatBuffer bufferD = ByteBuffer.allocateDirect(SIZE * 4)                                .order(ByteOrder.nativeOrder())                                .asFloatBuffer();


Tldr:

Use direct buffers only if we need to do efficient high-speed I/O.

If we need efficient high-speed non-I/O operations, default array is the best choice.

If we need to do buffer-like operations on a default array, and we can afford to be slow, then use an array-backed buffer.

Tsdr:

Your tests did not test any I/O operations and it's conclusion is therefore wrong.

Your conclusion states (emphasis not mine):

Direct buffers should only be used if you worry about memory usage and never access the underlying data. They are slightly slower than non-direct buffers, much slower if the underlying data is accessed, but use less memory. In addition there is an extra overhead when converting non-byte data (like float-arrays) into bytes when using a direct buffer.

That is clearly wrong. Direct buffers are meant to solve speed problems, not memory ones problems. Direct buffers should be used whenever you need high-performance I/O access. This includes file/network operations etc. It is definitely faster when used correctly and is in fact the fastest that Java API provides out-of-the-box.

When doing file/network operations, there is an extra overhead when converting non-byte data into bytes. This is true for everything, not just direct buffers.

Your conclusion also states:

Note that a backened-buffer has a Java Array backening the content of the buffer. It is recommended to do operations on this back-buffer instead of looping put/get.

This is true, but you are missing the whole point of array-backed buffers. Array-backed buffers is a facade pattern on top of arrays. Array-backed buffers will never be faster than arrays themselves since internally they have to use the array.

As such, they are there for convenience, not for speed. In other words, if you need speed, it's recommended to choose array over array-facade. If you need convenience/readability, it's recommended to choose array-facade over array for buffer-like operations on array.

Also read: