Span与Memory的诞生背景
在C#的发展历程中,高性能编程一直是重要的优化方向。传统的.NET内存处理,特别是涉及托管堆与非托管堆边界数据交互时,常常需要数据拷贝,这在处理大规模数据或对延迟敏感的场景下会成为性能瓶颈。为了解决这些问题,并在不牺牲安全性的前提下实现零拷贝(zero-copy)操作,.NET Core 2.1引入了两个关键的结构:Span和Memory。它们为编写高性能C#代码提供了强大的原生支持,是现代.NET高性能库(如System.IO.Pipelines)的基石。
理解Span:栈上的连续内存视图
Span是一个ref struct,这意味着它必须完全分配在栈上,而不能被装箱到托管堆。这个特性使其成为了一个轻量级、高性能的类型,但也限制了它的使用场景(例如,它不能作为类的字段,也不能用于异步操作)。Span的核心优势在于它提供了一种统一、安全的方式来访问各种类型的连续内存区域,无论是来自数组、字符串、栈内存(stackalloc)还是非托管内存。
Span的核心特性与使用
Span的主要价值在于“视图”功能。它本身不持有数据,而是指向一块已存在的内存。这种设计避免了不必要的数据复制。例如,您可以从一个数组中创建Span,对Span的修改会直接反映到原始数组上。
以下是一个简单的示例,展示如何使用Span操作数组的一部分:
```csharp// 创建一个数组int[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// 从数组创建一个Span,只包含索引2到5的元素(即3,4,5,6)Span span = data.AsSpan(2, 4);
// 通过Span修改数据for (int i = 0; i < span.Length; i++){ span[i] = 2;}
// 原始数组被修改:data 现在是 [1, 2, 6, 8, 10, 12, 7, 8, 9]Console.WriteLine(string.Join(, , data));```
此外,使用stackalloc可以在栈上分配内存并与Spa


1087

被折叠的 条评论
为什么被折叠?



