为什么 MemoryPool 比 ArrayPool 慢,分配的多?
Why is MemoryPool slower and allocates more than ArrayPool?
我不完全确定我在测试中是否做错了什么,但从我的结果来看,MemoryPool 始终比 ArrayPool 更慢并且分配的内存更多,因为您无论如何都可以将 Array 类型转换为 Memory,这有什么意义使用内存池?
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
上面是我的测试代码和结果。内存池实际上只是一般来说速度较慢,还是我遗漏了什么?如果 MemoryPool 实际上更慢,它有什么用例?
谢谢。
关于性能。
对memory.Span[i]
的重复调用是罪魁祸首。
GitHub 处的源代码显示在 属性 getter.
后面发生了相当多的处理
不要重复调用,而是将调用的结果存储在变量中
var span = memory.Span;
请参阅下面的完整代码块。
现在 Mean
个数字几乎相等。
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();
}
}
关于分配内存的不同。
这是设计使然。
已经有一个很好的 解释了这一点。
我不完全确定我在测试中是否做错了什么,但从我的结果来看,MemoryPool 始终比 ArrayPool 更慢并且分配的内存更多,因为您无论如何都可以将 Array 类型转换为 Memory,这有什么意义使用内存池?
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 |
上面是我的测试代码和结果。内存池实际上只是一般来说速度较慢,还是我遗漏了什么?如果 MemoryPool 实际上更慢,它有什么用例?
谢谢。
关于性能。
对memory.Span[i]
的重复调用是罪魁祸首。
GitHub 处的源代码显示在 属性 getter.
不要重复调用,而是将调用的结果存储在变量中
var span = memory.Span;
请参阅下面的完整代码块。
现在 Mean
个数字几乎相等。
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();
}
}
关于分配内存的不同。
这是设计使然。
已经有一个很好的