How costly is allocating new BufferAttribute array?

From the docs:

With regards to updating BufferGeometries, the most important thing to understand is that you cannot resize buffers (this is very costly, basically the equivalent to creating a new geometry). You can however update the content of buffers

Let’s say I pre-allocate an array with size of 1000 (using instancing):

geometry.addAttribute( 'myAttribute', new InstancedBufferAttribute(new Float32Array(1000), 3).setDynamic(true));
  1. What do i do if I need more than 1000? I don’t know prehand how much is the maximum i’ll need.
  2. Performance wise - is it better to pre-allocate let’s say 10,000 and re-allocate (how?) later, thus potentially wasting memory but if that’s a good guess than never re-allocate again?

All the examples use a fixed maximum but there is nothing saying how to resize it (even with the cost).

Resizing is definitely not possible since typed arrays are fixed size. If the array is completely filled, you have to create a new instance (which is expensive). I don’t have performance measurement data to illustrate the respective overhead but it’s a best practice to avoid buffer creation.

I don’t know prehand how much is the maximum i’ll need.

Sometimes you can delete old entries in a typed array. Or you use it in a circular manner. If it is full, you start at the beginning and overwrite existing values. Can’t you do something like that in your scenario?

Or make a system that has a tradeoff between various performance.

  1. Are you going to create mostly up to 1000, but sometimes 1001?

    create a bigger cache

  2. Are you sometimes creating up to 1000, other times up to 5000?

    either 1 or every time you go over a 1000 increment, make a new geometry

  3. Is this taking too long?

    try a chunk with 500, 200, 100…

This really depends on your use case, and the best answer is, you’ll have to try.

1 Like

If I have to reallocate the BufferAttribute, do I have to make a completly new geometry, or is there some way to just overwrite the BufferAttribute?

If the size of the buffer changes then yes, you have to call dispose() on the geometry and create a new one.

1 Like

Would it be better if individual BufferAttributes were disposable? A BufferGeometry may have multiple BufferAttributes, and there are cases where we only want to grow one of the BufferAttributes.

IMHO yes, it’d be nice if we could dispose BufferAttributes individually. Probably comes down to cost complexity of implementing it in the renderer, whether or not a pull request for that would be accepted.

I’m not sure whether resizing them individually makes sense or not though, probably they should all be the same length at any given time?

oops, oh, I was thinking uniforms, f.e. accessing data from A based on index of attribute B modulo A length.