Use C# compiler's static data support in Encoding.Preamble #20768
Conversation
Also avoid Array.Empty and just use default span for an empty preamble.
@@ -39,8 +39,8 @@ public sealed class UTF32Encoding : Encoding | |||
internal static readonly UTF32Encoding s_default = new UTF32Encoding(bigEndian: false, byteOrderMark: true); | |||
internal static readonly UTF32Encoding s_bigEndianDefault = new UTF32Encoding(bigEndian: true, byteOrderMark: true); | |||
|
|||
private static readonly byte[] s_bigEndianPreamble = new byte[4] { 0x00, 0x00, 0xFE, 0xFF }; | |||
private static readonly byte[] s_littleEndianPreamble = new byte[4] { 0xFF, 0xFE, 0x00, 0x00 }; | |||
private static ReadOnlySpan<byte> BigEndianPreamble => new byte[4] { 0x00, 0x00, 0xFE, 0xFF }; // uses C# compiler's optimization for static byte[] data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this just be inline in the Preamble property, similar to how GetPreamble() method is done? No need to define trivial properties for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice
I had gone through and made changes across the board within the coreclr repo some time ago but never submitted it. Is it worth pursuing and submitting a PR? I had similar changes for corefx in some branch that I need to find on my old machine. Let me know if I should dig it up. For example: ahsonkhan/corefx@21c3abb |
Sounds good to me. (BTW: The Hungarian |
This particular case is one where the consumer was already using the array as a span, so there was very little downside (though I did measure just to be sure, and microbenchmarks on, e.g. Encoding.UTF8.Preamble.Length, saw nice bumps). The other cases I found in corelib, though, which show up in your changes, too, all had a consumer expecting a byte[], which meant there could in theory be a greater chance of regression. Since there is a downside to the churn, and IMO a readability hit (it really looks like these call sites allocate), I think it's only worth doing for cases where you believe there will be measurable throughout or startup wins, or some other measurable benefit, and can then validate that. And in most of these cases, I think that's probably unlikely. But if you want to prove otherwise, great :) |
@dotnet-bot test Windows_NT x86 Release Innerloop Build and Test please |
ps Just saw Jan's response. If he thinks it's worthwhile, I defer to him :) |
This should be pretty much always worthwhile, in particular for large data blobs like the ones found in globalization. We should spot check the code generated by the JIT for this in several places to make sure that it works as expected and it is not hitting JIT optimization bug as it is often case with new constructs. |
…reclr#20768) * Use C# compiler's static data support in Encoding.Preamble Also avoid Array.Empty and just use default span for an empty preamble. * Address PR feedback Commit migrated from dotnet/coreclr@faa4c87
Also avoid Array.Empty and just use default span for an empty preamble.
Example IL (for UTF8Encoding.PreambleSpan):
cc: @jkotas, @tarekgh