पाठ 21 / 25

Allocation-Aware Code: Span, Strings and Boxing

Reduce allocations with Span<T>, StringBuilder and by avoiding boxing.

Fewer allocations, less GC work

In hot paths, every allocation adds GC work. A few techniques matter most. Span<T> and ReadOnlySpan<T> are stack-only views over contiguous memory (an array, part of a string, or stackalloc memory), so slicing and parsing need no copies; Memory<T> is the heap-storable counterpart for async code. Strings are immutable, so concatenating in a loop creates a new string each time; use StringBuilder, string.Join or interpolated string handlers. Boxing happens when a value type is converted to object or a non-generic interface, allocating a heap copy; generics avoid it. Use ArrayPool<T> to rent buffers. Above all, measure before optimising: BenchmarkDotNet gives reliable micro-benchmarks with allocation counts, and dotnet-counters and dotnet-trace show GC and CPU behaviour of a running app. Native AOT publishing compiles ahead of time for fast start-up and small memory use, with some reflection limits.

Parsing without allocating substrings

Slicing a span creates a view, not a new string.

using System.Text;

static int SumCsv(ReadOnlySpan<char> line)
{
    int total = 0;
    while (!line.IsEmpty)
    {
        int comma = line.IndexOf(',');
        ReadOnlySpan<char> field = comma < 0 ? line : line[..comma];
        total += int.Parse(field);
        line = comma < 0 ? ReadOnlySpan<char>.Empty : line[(comma + 1)..];
    }
    return total;
}

Console.WriteLine(SumCsv("10,20,30"));

var sb = new StringBuilder();
for (int i = 0; i < 1000; i++) sb.Append(i).Append(';');
string joined = sb.ToString();

// boxing: the int is copied to the heap as an object
object boxed = 42;
System.Collections.ArrayList old = new() { 1, 2, 3 };   // boxes each item; prefer List<int>

Optimise the measured hot path only

Span-heavy code is harder to read. Write clear code first, profile under realistic load, and optimise the few methods that dominate CPU or allocations.

त्वरित जाँच: What is Span<T> mainly used for?

  • Running code on another thread
  • Serialising objects to JSON
  • Working with slices of contiguous memory without copying or allocating
  • Storing data in a database
Answer

Working with slices of contiguous memory without copying or allocating — Span<T> is a lightweight view over memory that enables allocation-free slicing.