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.