Memory<T> 和 Span<T>
C# - Span 全面介绍:探索 .NET 新增的重要组成部分
Memory
零拷贝:Span
堆栈分配:Span
高效内存切片:你可以轻松地从现有的内存块中创建子视图,便于操作和管理数据。
示例:Memory
假设我们有一个方法,它需要处理一个包含多个数据块的文件,而每个数据块需要单独进行处理。通常我们可能会用数组来操作,但每次都需要创建新的数组或切片,可能会导致性能下降。
使用传统数组:
void ProcessData(byte[] data, int chunkSize) {
for (int i = 0; i < data.Length; i += chunkSize) {
byte[] chunk = new byte[chunkSize];
Array.Copy(data, i, chunk, 0, chunkSize); // 拷贝数据
ProcessChunk(chunk);
}
}
void ProcessChunk(byte[] chunk) {
// 对 chunk 进行处理
}
这种方法在每次处理数据块时都会创建新的数组并拷贝数据,这在处理大数据集时效率低下
在这个版本中,Slice 方法仅创建现有数据的视图,不进行数据复制,显著提高了性能。
使用 Memory
在处理异步操作时,Memory
async Task ProcessDataAsync(Memory<byte> data, int chunkSize) {
for (int i = 0; i < data.Length; i += chunkSize) {
Memory<byte> chunk = data.Slice(i, chunkSize); // 切片,无拷贝
await ProcessChunkAsync(chunk);
}
}
async Task ProcessChunkAsync(Memory<byte> chunk) {
// 对 chunk 进行异步处理
}
在这里,Memory
总结:
Span
Memory
通过 Memory
拓展:
ReadOnlySpan to Memory
[MethodImpl(MethodImplOptions.AggressiveInlining)] 是一个用于 C# 编程的标签,它建议编译器对标记的方法进行内联扩展。内联扩展是一种优化技术,编译器会将方法的代码直接插入到调用该方法的地方,从而减少函数调用的开销
fixed (T* ptr = &MemoryMarshal.GetReference(span)) 是一种在 C# 中使用指针和内存管理的用法。具体来说:
fixed 关键字:用于固定内存中的对象,防止垃圾回收器在代码执行期间移动它们。这样可以确保指针指向的内存地址在 fixed 代码块内是稳定的。
T* ptr:声明一个指向类型 T 的指针 ptr。
&MemoryMarshal.GetReference(span):获取 span 的第一个元素的引用,并取其地址。MemoryMarshal.GetReference 方法返回 span 第一个元素的引用,即使 span 为空

浙公网安备 33010602011771号