TArray allocator and memory pooling

Hi,
reading here : Optimizing TArray Usage for Performance - Unreal Engine

I learned about the ability to use a custom allocator for a TArray.

I have a TArray<FColor> of fixed size :

TArray<FColor> pixels;
pixels.Init(FColor(0, 0, 0, 255), fixedSize);

I would like to be able to reuse memory such that Init and FMemory::Free actually just flag in_use for a pre-allocated memory pool.
is there similar functionality in any UE4 allocators ?
any example code ?

Thanks,
Z

There’s a TCircularBuffer container:

They are a memory ring of fixed size capacity where new data overwrite the oldest.

Yes, just use the Reserve(int32) function within TArray. It will pre-allocate a block of memory for you.
If you don’t reserve the block of memory and you want to add in 1000 objects, the array will have to keep on resizing itself every time you exceed the bounds of the array with an “Add()”. Most of the time, nobody will notice anything in terms of performance, but if you have say, an array of pixels for a 1024x1024 image, it would be a really good idea to reserve that block in memory. You’d see a few ms in performance gain.

Not that I’m aware of. If reserve isn’t enough then one solution would be to pool your own array of TArray’s somewhere and just take/put back as need be. All depends on what your wanting to do. If you need to avoid the creation/destruction cost then you’ll want to store the array outside of things like loops, maybe in it’s own object pool or as a static array/global array (be wary of how this effects multithreading). And if you’d rather set flags for this datatype to determine if it’s valid or not, you can either leave the capacity as big as need by but somehow reduce the “size” so that it pretends to be empty array, or wrap this TArray in your own class/struct that has the flags and functions you need. I’m not saying what your asking for is bad, not at all. But it is a bit niche since most people can’t be bothered to pre allocate memory at all. Let alone re use it.

Some strange answers here. Just use



TArray::Reset(ElementCount)


Nukes existing elements and reallocates (if needed) to support the provided number of elements. TArray has both ‘Num’ and ‘Max’ - it doesn’t change the allocation (aka, the slow part) if you are calling Add() on an array that already has enough space allocated. Use it all the time.

Pretty rare that you need to create a custom Allocator outside of the ones which are already provided:

TDefaultAllocator<> - Allocates on-demand as needed.
TInlineAllocator<> - Allocates an initial block then adds as needed.
TFixedAllocator<> - Fixed allocation size, will assert and crash if you try to add more than the specified number of elements.

The number of elements needs to be known at compile time if you are using TInline/TFixed. Otherwise, just use Reserve() or Reset().

1 Like