Optimized Code Using Span<T>: An Introduction

Kalpani Ranasinghe
The Startup
Published in
4 min readJan 9, 2021

--

As a programmer, I strive to write codes that improve the performance of the overall application. At the beginning of my career last year, I came across this Span<T> type in C# when I’m searching for an efficient way to dealing with string operations such as Substring(), Split(), etc. So, I wanted to share some basic details about it with you.

What is Span<T>?

Span<T> is a new type introduced with C#7.2 and supported in the .NET Core 2.1 runtime.

Span<T > enables the representation of contiguous regions of arbitrary memory, regardless of whether that memory is associated with a managed object, is provided by native code via interop, or is on the stack. And it does so while still providing safe access with performance characteristics like that of arrays.

Span<T> has a related type ReadOnlySpan<T> which provides a read-only view of in-memory data. The ReadOnlySpan can be used to view the memory occupied by an immutable type like a String for example. You can think of Span<T> as a window into some existing memory, regardless of where it has been allocated.

Span<T> is defined as a ref struct, which means it is limited to being allocated only on the Stack. This reduces some potential use cases such as storing it as a field in a class or using it in async methods. The main reason for the ref struct design is to ensure that when using Span<T> we cause no additional heap allocations. This is one of the reasons it supports writing highly optimized codes.

Let’s look at some coding examples to understand the behavior of Span<T>.

Imagine you have an expression like the following, and you need to take the value out from it. Value is the substring after the last equal sign.

gender=female; or gender==female;

For that, you can write a simple method like this.

What it does is, it gets the index of the last equal character and uses that to get the substring representing the value. If the index is -1, we didn’t find any equal sign, so the method will return an empty string as our default result. If we do find the index, the method then uses the Substring method to extract value and return it.

Let’s optimize this code using Span<T> instead of using string operations.

Note that the optimized method, parameter “expression” is now of type ReadOnlySpan<char> and the return type is now also a ReadOnlySpan<char>.

First, in the same way as the previous code above, we look for the last index of the equal character. Again, if the index is -1, that means we didn’t find an equal sign and the method returns an empty ReadOnlySpan<char> result. If we do find an equal sign, we can now use a feature of Span called “Slicing”.

Slicing is a powerful operation where we can take an existing Span and Slice into a smaller window. When slicing, we can define the index of the starting position for the slice and optionally the length of the end position for the slice. If you omit the length, it will give a slice from the start position until the end of the Span.

Slicing is also a low-cost operation since we’re not copying anything. We’re just creating a new Span that represents a window into a subset of an existing memory range.

To get a better understanding check the following diagram.

Here we have created a Slice of the original Span to view the value “female” within it, without allocating any additional copies of the original memory. We take a slice of the value starting at the index after the last equal character. As we don’t specify a length, this slice will run to the end of the existing Span. Once we’ve sliced the original Span, it results in a new Span which contains the value and we return that as the result of the method.

So as you see, we can use Span<T> anywhere that you need to improve the performance and reduce the memory allocations when you need to do so. Although Span<T> can sound a little complex, the usage of it is pretty straightforward.

Hope you acquired some new knowledge about Span<T> from this article.

If you want to read more details about span, use the following links:

Thank you!

References

--

--

Kalpani Ranasinghe
The Startup

Backend Developer | Graduate Student at University of Oulu