Search code examples
c#stringperformancememorysubstring

Substring Without any Allocation Using Span<T>


How can we use Span<T> instead of string.Substring in order to eliminate the necessity of heap allocation? Let's say we have the following code:

var firstNameAndFamilyName="myname,myfamily";
var span = firstNameAndFamilyName.AsSpan().Slice(0,6);
var firstName = .... //  How can I get 'myname' without allocating any new memory on the heap?

Please note that I know that the string "myname,myfamily" is located on the heap and firstName needs to point to somewhere in the heap. My question is that how can we point to a subset of a string without coping that part to a new location of heap memory?

I know that a new constructor has been added to the String class which accepts ReadOnlySpan<T> like:

var firstName = new string(span);

But I couldn't find anywhere whether it's done by allocating on the heap or not.


Solution

  • As you are well aware, System.String is immutable. No buts, no ifs. If you have a Span<char> and want to treat them as string, new memory will be allocated.

    The good news is that with the introduction of Span<>, many of the built-in methods in the framework have been updated to accept it, in addition to accepting strings and arrays. To quote this MSDN article (I've added links to some examples):

    .. many such methods have been added across the framework. From System.Random to System.Text.StringBuilder to System.Net.Sockets, overloads have been added to make working with {ReadOnly}Span<T> and {ReadOnly}Memory<T> simple and efficient.

    This also includes all the numeric {Try}Parse(string) methods which will now have corresponding (ReadOnlySpan<char>) overloads.

    var str = "123,456";
    var span = str.AsSpan(0,3);
    var i = int.Parse(span); // 123
    

    So instead of getting a string out of your spans, see if what you're trying to achieve can utilise the Span<> directly.