How is the new C# Span<T> different from ArraySegment<T>?

Solution 1:

Span<T> does not replace anything. It's value-added. It provides a type-safe view into continuous segments of memory which can be allocated in many different ways: either as a managed array, a stack-based memory or unmanaged memory.

ArraySegment<T> is limited to managed arrays. You can't use it to wrap data allocated on the stack using stackalloc. Span<T> allows you to do that.

ArraySegment<T> also does not provide a read-only view into the underlying array. ReadOnlySpan<T> gives you that.

Span<T> is not supposed to replace arrays. At the end of the day it's just a view into data. That data has to be allocated somehow, and in managed world that allocation, for most cases, will be an array allocation. So you still need arrays.

You should use Span<T> if you want your code to be able to manipulate more than just arrays. E.g. consider a parsing library. Right now, to allow it to work with arrays, stack-allocated memory and unmanaged memory, it has to provide multiple entry points in the API for each of these, and use unsafe code to actually manipulate the data. It also probably would need to expose a string-based API to be used by people who have their data allocated as strings. With Span and ReadOnlySpan you can merge all that logic to a single, Span-based solution which will be applicable in all these scenarios.

Span<T> is definitely not going to be something that's used by everybody and very often. It's a highly specialized part of .NET framework useful mostly to library authors and in very high performance critical scenarios. E.g. Kestrel, the web service behind ASP.NET Core will get a lot of performance benefits from moving to Span<T> because e.g. parsing the request can be done using Span<T> and stack-allocated memory, which puts no pressure on GC. But you, writing websites and services based on ASP.NET Core, don't necessary have to use it.

Solution 2:

From MSDN Magazine: Span is defined in such a way that operations can be as efficient as on arrays: indexing into a span doesn’t require computation to determine the beginning from a pointer and its starting offset, as the ref field itself already encapsulates both. (By contrast, ArraySegment has a separate offset field, making it more expensive both to index into and to pass around.)

Also, while ArraySegment implements IEnumerable, Span doesn't.