Skip to content

Commit db03493

Browse files
Optimize compression of embedded PDB file. (#113803)
* Optimize compression of embedded PDB file. Instead of buffering the compressed bytes to a `MemoryStream`, we directly write them to the `BlobBuilder`. This is achieved by defining a write-only stream type that wraps a `BlobBuilder`. * Simplify writing blob builder to stream.
1 parent ae64202 commit db03493

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/DebugDirectory/DebugDirectoryBuilder.EmbeddedPortablePdb.cs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,33 @@ private static int WriteEmbeddedPortablePdbData(BlobBuilder builder, BlobBuilder
4747
builder.WriteInt32(debugMetadata.Count);
4848

4949
// compressed data:
50-
var compressed = new MemoryStream();
51-
using (var deflate = new DeflateStream(compressed, CompressionLevel.Optimal, leaveOpen: true))
50+
using (var deflate = new DeflateStream(new BlobBuilderStream(builder), CompressionLevel.Optimal, leaveOpen: true))
5251
{
53-
foreach (var blob in debugMetadata.GetBlobs())
54-
{
55-
var segment = blob.GetBytes();
56-
deflate.Write(segment.Array!, segment.Offset, segment.Count);
57-
}
52+
debugMetadata.WriteContentTo(deflate);
5853
}
5954

60-
builder.WriteBytes(compressed.GetBuffer(), 0, (int)compressed.Length);
61-
6255
return builder.Count - start;
6356
}
6457

58+
/// <summary>
59+
/// Provides a <see cref="Stream"/> interface to write to a <see cref="BlobBuilder"/>.
60+
/// </summary>
61+
/// <param name="builder">The blob builder to write data to.</param>
62+
private sealed class BlobBuilderStream(BlobBuilder builder) : Stream
63+
{
64+
public override bool CanRead => false;
65+
public override bool CanSeek => false;
66+
public override bool CanWrite => true;
67+
public override long Length => throw new NotSupportedException();
68+
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
69+
public override void Flush() { }
70+
public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException();
71+
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
72+
public override void SetLength(long value) => throw new NotSupportedException();
73+
public override void Write(byte[] buffer, int offset, int count) => builder.WriteBytes(buffer, offset, count);
74+
#if NET
75+
public override void Write(ReadOnlySpan<byte> buffer) => builder.WriteBytes(buffer);
76+
#endif
77+
}
6578
}
6679
}

0 commit comments

Comments
 (0)