Search code examples
c#performancesystem.memory

Find position of Span<T> in an array


Span points to a memory area. Given that I know what memory area it is (i.e. array), can I (efficiently) figure out what first element in the array it is pointing to? I figured since it is pointing to non-pinned memory this information has to be stored somewhere, as address has to be updated by GC.

var buffer = new byte[100];
var span = new Span<byte>(buffer);
span = span.Slice(10, 5);
// How can I figure out where in buffer this span starts?

Solution

  • See MemoryExtensions.Overlaps<T>()

    Example

    var arrayOfBytes = Enumerable.Range(0, 255).Select(n => (byte)n).ToArray();
    var spanOfBytes = new Span<byte>(arrayOfBytes).Slice(10, 5);
    MemoryExtensions.Overlaps<byte>(arrayOfBytes, spanOfBytes, out var ofsByte);
    Console.WriteLine($"Offset of spanOfBytes in arrayOfBytes is {ofsByte}");
    
    var arrayOfInt = Enumerable.Range(0, 255).Select(n => n).ToArray();
    var spanOfInt = new Span<int>(arrayOfInt).Slice(15, 3);
    MemoryExtensions.Overlaps<int>(arrayOfInt, spanOfInt, out var ofsInt);
    Console.WriteLine($"Offset of spanOfInt in arrayOfInt is {ofsInt}");
    

    Result

    Offset of spanOfBytes in arrayOfBytes is 10
    Offset of spanOfInt in arrayOfInt is 15
    

    Available (by extension package) for .NetFx 4.7 and from .NET Core 2.1