关于 Span 的一切:探索新的 .NET 明星: 3.什么是 Memory<T>,以及为什么你需要它?
3. 什么是 Memory,以及为什么你需要它?
Span
var arr = new byte[100];
Span interiorRef1 = arr.AsSpan(start: 20);
Span interiorRef2 = new Span(arr, 20, arr.Length – 20);
Span interiorRef3 =
MemoryMarshal.CreateSpan(arr, ref arr[20], arr.Length – 20);
这些引用被称为中间指针,跟踪它们对于 .NET 运行时的垃圾回收器来说是昂贵的操作。因此,运行时限制这些 ref 只能存在于堆栈,因为它提供了隐式的可能存在的中间指针数量的低限制。
进一步说,如前所展示的那样,Span
因此,Spanwhere T: ref struct 约束存在的原因 )。
这些限制对很多场景并不重要,特别是在计算密集和同步处理的函数中。但是异步函数就是另外一回事了。在本文开始引用的多数问题是围绕数组来的,数组切片、原生内存等等不管是同步还是异步都存在。然而,如果 Span
Memory
public readonly struct Memory
{
private readonly object _object;
private readonly int _index;
private readonly int _length;
...
}
你可以通过数组来创建 Memory
static async Task ChecksumReadAsync(Memory buffer, Stream stream)
{
int bytesRead = await stream.ReadAsync(buffer);
return Checksum(buffer.Span.Slice(0, bytesRead));
// Or buffer.Slice(0, bytesRead).Span
}
static int Checksum(Span buffer) { ... }
与 Span
图 1 在 Span 相关的类型之间进行不分配内存/不复制的转换
| 来源 | 目标 | 机制 |
|---|---|---|
| ArraySegment |
Memory |
Implicit cast, AsMemory method |
| ArraySegment |
ReadOnlyMemory |
Implicit cast, AsMemory method |
| ArraySegment |
ReadOnlySpan |
Implicit cast, AsSpan method |
| ArraySegment |
Span |
Implicit cast, AsSpan method |
| ArraySegment |
T[] | Array property |
| Memory |
ArraySegment |
MemoryMarshal.TryGetArray method |
| Memory |
ReadOnlyMemory |
Implicit cast, AsMemory method |
| Memory |
Span |
Span property |
| ReadOnlyMemory |
ArraySegment |
MemoryMarshal.TryGetArray method |
| ReadOnlyMemory |
ReadOnlySpan |
Span property |
| ReadOnlySpan |
ref readonly T | Indexer get accessor, marshaling methods |
| Span |
ReadOnlySpan |
Implicit cast, AsSpan method |
| Span |
ref T | Indexer get accessor, marshaling methods |
| String | ReadOnlyMemory |
AsMemory method |
| String | ReadOnlySpan |
Implicit cast, AsSpan method |
| T[] | ArraySegment |
Ctor, Implicit cast |
| T[] | Memory |
Ctor, Implicit cast, AsMemory method |
| T[] | ReadOnlyMemory |
Ctor, Implicit cast, AsMemory method |
| T[] | ReadOnlySpan |
Ctor, Implicit cast, AsSpan method |
| T[] | Span |
Ctor, Implicit cast, AsSpan method |
| void* | ReadOnlySpan |
Ctor |
| void* | Span |
Ctor |
你会注意到,Memory