Home > Enterprise >  Why is MemoryPool slower and allocates more than ArrayPool?
Why is MemoryPool slower and allocates more than ArrayPool?

Time:06-05

I'm not entirely sure if I have done something wrong in my tests, but from my results MemoryPool is consistently slower and allocates more memory than ArrayPool, since you can convert Array type to Memory anyway, what is the point of using MemoryPool?

using System.Buffers;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Attributes;

BenchmarkRunner.Run<test>();

[MemoryDiagnoser]
public class test
{
    [Benchmark]
    public void WithArrayPool()
    {
        ArrayPool<int> pool = ArrayPool<int>.Shared;

        for (int z = 0; z < 100; z  )
        {
            var memory = pool.Rent(2347);
            
            for (int i = 0; i < memory.Length; i  )
            {
                memory[i] = i   1;
            }

            int total = 0;

            for (int i = 0; i < memory.Length; i  )
            {
                total  = memory[i];
            }

            pool.Return(memory);
        }
    }

    [Benchmark]
    public void WithMemoryPool()
    {
        MemoryPool<int> pool = MemoryPool<int>.Shared;

        for (int z = 0; z < 100; z  )
        {
            var rentedArray = pool.Rent(2347);
            var memory = rentedArray.Memory;
            
            for (int i = 0; i < memory.Length; i  )
            {
                memory.Span[i] = i   1;
            }

            int total = 0;

            for (int i = 0; i < memory.Length; i  )
            {
                total  = memory.Span[i];
            }

            rentedArray.Dispose();
        }
    }
}
Method Mean Error StdDev Allocated
WithArrayPool 770.2 us 2.27 us 2.01 us 1 B
WithMemoryPool 1,714.6 us 0.56 us 0.50 us 2,402 B

My test code with results is above. Is Memory Pool actually just slower in general or is there something I am missing? If MemoryPool is in fact slower, what use case does it have?

Thanks.

CodePudding user response:

About the performance.

The repeated call to memory.Span[i] is the culprit.
The source code at GitHub shows that quite some handling occurs behind that property getter.

Instead of repeating that call, store the result of that call in a variable

var span = memory.Span;

See full code block below.

Now the Mean numbers are almost equal.

Method Mean Error StdDev Median Gen 0 Allocated
WithArrayPool 333.4 us 2.34 us 5.15 us 331.0 us - -
WithMemoryPool 368.6 us 7.08 us 5.53 us 366.7 us 0.4883 2,400 B

[Benchmark]
public void WithMemoryPool()
{
    MemoryPool<int> pool = MemoryPool<int>.Shared;

    for (int z = 0; z < 100; z  )
    {
        var rentedArray = pool.Rent(2347);
        var memory = rentedArray.Memory;
        var span = memory.Span; 

        for (int i = 0; i < memory.Length; i  )
        {
            span[i] = i   1;
        }

        int total = 0;

        for (int i = 0; i < memory.Length; i  )
        {
            total  = span[i];
        }

        rentedArray.Dispose();
    }
}

About the difference in allocated memory.

That's by design.
There's already an very good post that explains this.

  • Related