From a26198a6b0488bd730bb942e3cf226ea9f0b0646 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Sat, 4 Apr 2026 11:04:51 +0100 Subject: [PATCH] use pooled memory streams for better performance --- src/SharpCompress/Archives/Tar/TarArchive.Async.cs | 2 +- src/SharpCompress/Archives/Tar/TarArchive.cs | 2 +- src/SharpCompress/Common/SevenZip/ArchiveReader.cs | 2 +- .../Common/SevenZip/SevenZipFilesInfo.cs | 3 ++- .../Compressors/LZMA/Lzma2EncoderStream.cs | 5 +++-- src/SharpCompress/Compressors/PPMd/PpmdStream.cs | 3 ++- .../Compressors/Squeezed/SqueezedStream.Async.cs | 7 ++++--- .../Compressors/Squeezed/SqueezedStream.cs | 5 +++-- src/SharpCompress/Writers/SevenZip/SevenZipWriter.cs | 4 ++-- src/SharpCompress/packages.lock.json | 12 ++++++------ 10 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/SharpCompress/Archives/Tar/TarArchive.Async.cs b/src/SharpCompress/Archives/Tar/TarArchive.Async.cs index ac584e1b..45e5b1ca 100644 --- a/src/SharpCompress/Archives/Tar/TarArchive.Async.cs +++ b/src/SharpCompress/Archives/Tar/TarArchive.Async.cs @@ -141,7 +141,7 @@ public partial class TarArchive using (var entryStream = entry.OpenEntryStream()) { - using var memoryStream = new MemoryStream(); + using var memoryStream = new PooledMemoryStream(); await entryStream.CopyToAsync(memoryStream).ConfigureAwait(false); memoryStream.Position = 0; var bytes = memoryStream.ToArray(); diff --git a/src/SharpCompress/Archives/Tar/TarArchive.cs b/src/SharpCompress/Archives/Tar/TarArchive.cs index fdd8ac3a..44238549 100644 --- a/src/SharpCompress/Archives/Tar/TarArchive.cs +++ b/src/SharpCompress/Archives/Tar/TarArchive.cs @@ -151,7 +151,7 @@ public partial class TarArchive using (var entryStream = entry.OpenEntryStream()) { - using var memoryStream = new MemoryStream(); + using var memoryStream = new PooledMemoryStream(); entryStream.CopyTo(memoryStream, Constants.BufferSize); memoryStream.Position = 0; var bytes = memoryStream.ToArray(); diff --git a/src/SharpCompress/Common/SevenZip/ArchiveReader.cs b/src/SharpCompress/Common/SevenZip/ArchiveReader.cs index 3a4e5622..b75d123c 100644 --- a/src/SharpCompress/Common/SevenZip/ArchiveReader.cs +++ b/src/SharpCompress/Common/SevenZip/ArchiveReader.cs @@ -1182,7 +1182,7 @@ internal partial class ArchiveReader } else { - _stream = new MemoryStream(); + _stream = new PooledMemoryStream(); } _rem = _db._files[index].Size; } diff --git a/src/SharpCompress/Common/SevenZip/SevenZipFilesInfo.cs b/src/SharpCompress/Common/SevenZip/SevenZipFilesInfo.cs index f5fd410e..9162474b 100644 --- a/src/SharpCompress/Common/SevenZip/SevenZipFilesInfo.cs +++ b/src/SharpCompress/Common/SevenZip/SevenZipFilesInfo.cs @@ -2,6 +2,7 @@ using System; using System.IO; using System.Text; using SharpCompress.Compressors.LZMA.Utilities; +using SharpCompress.IO; namespace SharpCompress.Common.SevenZip; @@ -215,7 +216,7 @@ internal sealed class SevenZipFilesInfoWriter Action writeData ) { - using var dataStream = new MemoryStream(); + using var dataStream = new PooledMemoryStream(); writeData(dataStream); stream.WriteByte((byte)propertyId); diff --git a/src/SharpCompress/Compressors/LZMA/Lzma2EncoderStream.cs b/src/SharpCompress/Compressors/LZMA/Lzma2EncoderStream.cs index 1642be44..84bd3f00 100644 --- a/src/SharpCompress/Compressors/LZMA/Lzma2EncoderStream.cs +++ b/src/SharpCompress/Compressors/LZMA/Lzma2EncoderStream.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using SharpCompress.IO; namespace SharpCompress.Compressors.LZMA; @@ -158,7 +159,7 @@ internal sealed class Lzma2EncoderStream : Stream } using var inputMs = new MemoryStream(data.ToArray(), writable: false); - using var outputMs = new MemoryStream(); + using var outputMs = new PooledMemoryStream(); encoder.Code(inputMs, outputMs, data.Length, -1, null); @@ -190,7 +191,7 @@ internal sealed class Lzma2EncoderStream : Stream decoder.SetDecoderProperties(props); using var input = new MemoryStream(compressedData); - using var output = new MemoryStream(); + using var output = new PooledMemoryStream(); decoder.Code(input, output, compressedData.Length, uncompressedSize, null); return (int)input.Position; diff --git a/src/SharpCompress/Compressors/PPMd/PpmdStream.cs b/src/SharpCompress/Compressors/PPMd/PpmdStream.cs index 902246d7..210f5aa5 100644 --- a/src/SharpCompress/Compressors/PPMd/PpmdStream.cs +++ b/src/SharpCompress/Compressors/PPMd/PpmdStream.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using SharpCompress.Compressors.LZMA.RangeCoder; using SharpCompress.Compressors.PPMd.H; using SharpCompress.Compressors.PPMd.I1; +using SharpCompress.IO; namespace SharpCompress.Compressors.PPMd; @@ -179,7 +180,7 @@ public class PpmdStream : Stream { if (_compress) { - _model.EncodeBlock(_stream, new MemoryStream(), true); + _model.EncodeBlock(_stream, new PooledMemoryStream(), true); } } base.Dispose(disposing); diff --git a/src/SharpCompress/Compressors/Squeezed/SqueezedStream.Async.cs b/src/SharpCompress/Compressors/Squeezed/SqueezedStream.Async.cs index d8090dca..6a0cfcda 100644 --- a/src/SharpCompress/Compressors/Squeezed/SqueezedStream.Async.cs +++ b/src/SharpCompress/Compressors/Squeezed/SqueezedStream.Async.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using SharpCompress.Common; using SharpCompress.Compressors.RLE90; +using SharpCompress.IO; namespace SharpCompress.Compressors.Squeezed; @@ -54,14 +55,14 @@ public partial class SqueezeStream if (bytesRead != 2) { - return new MemoryStream(Array.Empty()); + return new PooledMemoryStream(); } int numnodes = numNodesBytes[0] | (numNodesBytes[1] << 8); if (numnodes >= NUMVALS || numnodes == 0) { - return new MemoryStream(Array.Empty()); + return new PooledMemoryStream(); } var dnode = new int[numnodes, 2]; @@ -82,7 +83,7 @@ public partial class SqueezeStream } var bitReader = new BitReader(_stream); - var huffmanDecoded = new MemoryStream(); + var huffmanDecoded = new PooledMemoryStream(); int i = 0; while (true) diff --git a/src/SharpCompress/Compressors/Squeezed/SqueezedStream.cs b/src/SharpCompress/Compressors/Squeezed/SqueezedStream.cs index 09aa8b2c..f6a40f1c 100644 --- a/src/SharpCompress/Compressors/Squeezed/SqueezedStream.cs +++ b/src/SharpCompress/Compressors/Squeezed/SqueezedStream.cs @@ -4,6 +4,7 @@ using System.IO; using System.Text; using SharpCompress.Common; using SharpCompress.Compressors.RLE90; +using SharpCompress.IO; namespace SharpCompress.Compressors.Squeezed; @@ -67,7 +68,7 @@ public partial class SqueezeStream : Stream if (numnodes >= NUMVALS || numnodes == 0) { - return new MemoryStream(Array.Empty()); + return new PooledMemoryStream(); } var dnode = new int[numnodes, 2]; @@ -78,7 +79,7 @@ public partial class SqueezeStream : Stream } var bitReader = new BitReader(_stream); - var huffmanDecoded = new MemoryStream(); + var huffmanDecoded = new PooledMemoryStream(); int i = 0; while (true) diff --git a/src/SharpCompress/Writers/SevenZip/SevenZipWriter.cs b/src/SharpCompress/Writers/SevenZip/SevenZipWriter.cs index a785aaf2..501959ee 100644 --- a/src/SharpCompress/Writers/SevenZip/SevenZipWriter.cs +++ b/src/SharpCompress/Writers/SevenZip/SevenZipWriter.cs @@ -171,7 +171,7 @@ public partial class SevenZipWriter : AbstractWriter var filesInfo = new SevenZipFilesInfoWriter { Entries = entries.ToArray() }; // Write header to a temporary stream first - using var headerStream = new MemoryStream(); + using var headerStream = new PooledMemoryStream(); ArchiveHeaderWriter.WriteRawHeader(headerStream, mainStreamsInfo, filesInfo); // Optionally compress the header @@ -212,7 +212,7 @@ public partial class SevenZipWriter : AbstractWriter }; // Write encoded header to a second temporary stream - using var encodedHeaderStream = new MemoryStream(); + using var encodedHeaderStream = new PooledMemoryStream(); ArchiveHeaderWriter.WriteEncodedHeader(encodedHeaderStream, headerStreamsInfo); // Write the encoded header to the output diff --git a/src/SharpCompress/packages.lock.json b/src/SharpCompress/packages.lock.json index b44de28b..5059aafe 100644 --- a/src/SharpCompress/packages.lock.json +++ b/src/SharpCompress/packages.lock.json @@ -268,9 +268,9 @@ "net10.0": { "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[10.0.2, )", - "resolved": "10.0.2", - "contentHash": "sXdDtMf2qcnbygw9OdE535c2lxSxrZP8gO4UhDJ0xiJbl1wIqXS1OTcTDFTIJPOFd6Mhcm8gPEthqWGUxBsTqw==" + "requested": "[10.0.0, )", + "resolved": "10.0.0", + "contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", @@ -442,9 +442,9 @@ "net8.0": { "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[8.0.23, )", - "resolved": "8.0.23", - "contentHash": "GqHiB1HbbODWPbY/lc5xLQH8siEEhNA0ptpJCC6X6adtAYNEzu5ZlqV3YHA3Gh7fuEwgA8XqVwMtH2KNtuQM1Q==" + "requested": "[8.0.22, )", + "resolved": "8.0.22", + "contentHash": "MhcMithKEiyyNkD2ZfbDZPmcOdi0GheGfg8saEIIEfD/fol3iHmcV8TsZkD4ZYz5gdUuoX4YtlVySUU7Sxl9SQ==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct",