The Abstraction: Span & Memory
🛡️ The Abstraction: Span & Memory
In the previous module, we saw how unsafe pointers allow us to manipulate memory directly. However, pointers are dangerous. Span<T> is the modern .NET solution that provides the performance of pointers with the safety of managed code.
🏗️ 1. Span<T>: The Safe Pointer
Span<T> is a ref struct that lives on the stack. It contains a pointer and a length, but the runtime ensures you never step outside the bounds.
🧩 The Upgrade
- The Mechanic (Pointers):
int* p = &myInt;(Fast but dangerous) - The Abstraction (Span):
Span<int> s = myBuffer.AsSpan();(Fast and safe)
How it looks in code:
byte[] largeBuffer = new byte[1024];
// Pointing a 'Window' at a slice of memory
Span<byte> slice = largeBuffer.AsSpan().Slice(10, 50);
slice[0] = 42; // This actually modifies largeBuffer[10]!🏗️ 2. Memory<T>: Span for the Heap
Span<T> cannot be used in async methods or stored in classes because it is a ref struct (it must stay on the stack). For those cases, we use Memory<T>.
| Feature | Span<T> | Memory<T> |
|---|---|---|
| Location | Stack-only | Stack or Heap |
| Async Support | No | Yes |
| Performance | Maximum | High |
🏗️ 3. SIMD: Vectorization (NumPy in C#)
When you need to process large arrays of numbers (like in AI or Data Engineering), you don’t use a for loop. You use SIMD (Single Instruction, Multiple Data).
using System.Runtime.Intrinsics;
using System.Numerics;
// Vectorized addition (Adds 8 ints at once on AVX2)
var v1 = new Vector<int>(array1);
var v2 = new Vector<int>(array2);
var result = v1 + v2;🚀 The Abstraction’s Advantage
- Safety: No more
AccessViolationException. - Unified API: Works with arrays, strings, and unmanaged memory (
stackalloc) using the same syntax. - Zero-Copy: Parsing strings like
JSONorXMLwithout allocating new strings for every property.