Writing to Buffers (nio) performance issue

While programming an application with JOGL, I decided to use vertex-arrays to store some data in to send to the VRAM, forcing me to use nio-buffers.

Code was like:


FloatBuffer vertex;
FloatBuffer normal;
FloatBuffer texcoord;

for(every visible tree)
{
   vertex.put(float[]);
   normal.put(float[]);
   texcoord.put(float[]);
}

Dead-slow… Maybe not surprising for you, but for me it was. Frustrated I wondered what was so slow here, and tried the following:


FloatBuffer vertex;
FloatBuffer normal;
FloatBuffer texcoord;
float[] vertexArray;
float[] normalArray;
float[] texcoordArray;

for(every visible tree)
{
   System.arraycopy(append float[] -> vertexArray);
   System.arraycopy(append float[] -> normalArray);
   System.arraycopy(append float[] -> texcoordArray);
}

vertex.put(vertexArray);
normal.put(normalArray);
texcoord.put(texcoordArray);

It was 15x faster! (and 15x is a LOT)

So I was wondering… what is causing directly putting data in (Float)Buffers to be so inefficient (6% of performance in code#2).
~~
Note that the FloatBuffers were native.

Going across JNI is the performance problem. Never use the single put/get methods if you want any form of performance. Stick to using the bulk methods and set the entire array at once.

[quote]Going across JNI is the performance problem.
[/quote]
I thought the buffer operations were supposed to be intrinsified. If you have to make a JNI call every time, then the overhead is absolutely ridiculous and makes direct byte buffers nearly useless.

God bless,
-Toby Reyelts

The problem may be in the first place is actually that he’s doing lots of weeny little copies from all over RAM, and mostly that won’t be intrinsified as it’s rather difficult to check the bounds etc. and it’ll bugger the caches.

If you blat all the arrays into one big array and then copy the lot in one go to a buffer you’re probably going to be kinder to the cache and avoid the checking overheads at the same time. Probably.

Cas :slight_smile: