-
-
Notifications
You must be signed in to change notification settings - Fork 887
Description
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