Home > database >  Shared array pool ends up using way more memory than without
Shared array pool ends up using way more memory than without

Time:12-16

To try minimize garbage collection, I profiled my application and found out the following property.

Naturally, I decided to give a try in using a shared pool.

Not only that didn't work out at all, but the memory usage bloated in the mean time:

Self (Allocations) Self Size (Bytes)
3,848 3,293,888
21,098 70,720,496
partial class ImDrawData
{
    private ImDrawList[]? CmdListsArray;

    public unsafe ImDrawList[] CmdLists
    {
        get
        {
            var pool = ArrayPool<ImDrawList>.Shared;

            if (CmdListsArray != null)
            {
                pool.Return(CmdListsArray);
            }

            var size = CmdListsCount;

            var rent = CmdListsArray = pool.Rent(size);

            var data = (IntPtr*)((__Internal*)__Instance)->CmdLists;

            for (var i = 0; i < size; i  )
            {
                rent[i] = ImDrawList.__CreateInstance(data[i]);
            }

            return rent;
        }
    }
}

The original code would simply create a new array each time the property was queried.

Question:

How can I implement an effective array pool for that particular property?

CodePudding user response:

I ended up fixing the problem with a good old C-like approach:

The consumer is now responsible about passing the array.

public unsafe int GetCmdLists([NotNull] ref ImDrawList[]? lists)
{
    var count = CmdListsCount;

    if (lists is null || lists.Length < count)
    {
        Array.Resize(ref lists, count);
    }

    var input = (IntPtr*)((__Internal*)__Instance)->CmdLists;

    for (var i = 0; i < count; i  )
    {
        lists[i] = ImDrawList.__CreateInstance(input[i]);
    }

    return count;
}

By allocating a sufficiently large array for common use, I now get zero reallocations and zero GC.

  • Related