Skip to content

Modify static readonly byte arrays to take advantage of compiler functionality. #854

@tannergooding

Description

@tannergooding

The C# compiler added some optimizations around static readonly arrays that will emit them as compile time constants embedded in the PE file.

For most primitive types something like static readonly uint[] x = new uint[] { 1, 2, 3 }; will be compiled down to the following code in the static ctor for the containing type:

uint[] array = new uint[3];
RuntimeHelpers.InitializeArray(array, &global::<PrivateImplementationDetails>.7037807198C22A7D2B0807371D763779A84FDFCF);
x = array;

The RuntimeHelpers.InitializeArray function effectively performs a memcpy of the constant data into the array. This function also handles the endian conversion on non little-endian machines.

For byte and sbyte in particular, there is no endian conversion required and an additional optimization is available. Namely, you can change the signature from static readonly byte[] x = new byte[] { 1, 2, 3 }; to static ReadOnlySpan<byte> x => new byte[] { 1, 2, 3 };. This property pattern will get optimized down to:

static ReadOnlySpan<byte> x => new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.7037807198C22A7D2B0807371D763779A84FDFCF, 3);

In this case, the ReadOnlySpan is just initialized with a direct pointer to the compile time constant data.

ImageSharp should review their various static readonly arrays and determine when it would be applicable to take advantage of this optimization. In cases where it is not returning a byte[] but where all elements can fit within a byte or sbyte, it should additionally be considered to change the backing storage to be byte or sbyte.

More details can be found: dotnet/roslyn#24621

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions