Optimize ManifestResourceStream.Read(Span<byte>) (#69412)
authorEric Erhardt <eric.erhardt@microsoft.com>
Tue, 17 May 2022 10:55:34 +0000 (05:55 -0500)
committerGitHub <noreply@github.com>
Tue, 17 May 2022 10:55:34 +0000 (06:55 -0400)
ManifestResourceStream is derived from UnmanagedMemoryStream. UnmanagedMemoryStream optimizes Read(Span<byte>), but only if the instance is concretely an UnmanagedMemoryStream. This is to protect in case the derived Stream overriddes Read(byte[], int, int) prior to the Read(Span<byte>) overload being introduced.

Optimize ManifestResourceStream by overriding Read(Span<byte>) and call ReadCore, so the Stream.Read(Span<byte>) logic of using a pooled byte[] buffer isn't used.

src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs

index 8fe1d3b..c6c2000 100644 (file)
@@ -36,12 +36,18 @@ namespace System.Reflection
 
         private sealed class ManifestResourceStream : UnmanagedMemoryStream
         {
+            // ensures the RuntimeAssembly is kept alive for as long as the stream lives
             private RuntimeAssembly _manifestAssembly;
 
             internal unsafe ManifestResourceStream(RuntimeAssembly manifestAssembly, byte* pointer, long length, long capacity, FileAccess access) : base(pointer, length, capacity, access)
             {
                 _manifestAssembly = manifestAssembly;
             }
+
+            // override Read(Span<byte>) because the base UnmanagedMemoryStream doesn't optimize it for derived types
+            public override int Read(Span<byte> buffer) => ReadCore(buffer);
+
+            // NOTE: no reason to override Write(Span<byte>), since a ManifestResourceStream is read-only.
         }
 
         internal object SyncRoot