In recent .NET releases, Span<T>
and Memory<T>
have become essential tools for high‑performance scenarios. This post explores their differences, when to use each, and provides practical examples.
What is Span<T>
?
Span<T>
is a stack‑only type that provides a view over contiguous memory. It can reference arrays, String
, or even unmanaged memory. Because it's a ref struct, it cannot be boxed or captured by async lambdas.
void ProcessData(ReadOnlySpan<byte> data)
{
for (int i = 0; i < data.Length; i++)
{
// Process each byte...
}
}
What is Memory<T>
?
Memory<T>
is the heap‑compatible counterpart of Span<T>
. It can be stored, passed around async methods, and used where a ref struct is not allowed. To access its contents, you retrieve a Span<T>
via Memory<T>.Span
.
async Task<int> ReadFileAsync(string path)
{
var memory = new Memory<byte>(new byte[4096]);
using var stream = File.OpenRead(path);
int read = await stream.ReadAsync(memory);
// Work with memory.Span here...
return read;
}
When to choose one over the other?
- Use
Span<T>
for short‑lived, high‑performance code that stays on the stack. - Use
Memory<T>
when you need to store the reference or use it asynchronously.
Both types dramatically reduce allocations compared to traditional arrays or strings, especially in parsers and serializers.
Comments (3)
Span<T>
extremely useful in my JSON parser.Memory<T>
withIAsyncEnumerable
?Span<T>
in public APIs; it forces callers to use ref structs.