diff --git a/AGENTS.md b/AGENTS.md index 6ecf801d3..32bbb9426 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -103,8 +103,11 @@ tests/ ### Factory Pattern Factory implementations can implement one or more interfaces (`IArchiveFactory`, `IReaderFactory`, `IWriterFactory`) depending on format capabilities: - `ArchiveFactory.OpenArchive()` - Opens archive API objects from seekable streams/files +- `ArchiveFactory.OpenAsyncArchive()` - Opens async archive API objects for async archive use cases - `ReaderFactory.OpenReader()` - Auto-detects and opens forward-only readers +- `ReaderFactory.OpenAsyncReader()` - Auto-detects and opens forward-only async readers - `WriterFactory.OpenWriter()` - Creates a writer for a specified `ArchiveType` +- `WriterFactory.OpenAsyncWriter()` - Creates an async writer for async write scenarios - Factories located in: `src/SharpCompress/Factories/` ## Nullable Reference Types @@ -132,6 +135,9 @@ SharpCompress supports multiple archive and compression formats: ### Async/Await Patterns - All I/O operations support async/await with `CancellationToken` - Async methods follow the naming convention: `MethodNameAsync` +- For async archive scenarios, prefer `ArchiveFactory.OpenAsyncArchive(...)` over sync `OpenArchive(...)`. +- For async forward-only read scenarios, prefer `ReaderFactory.OpenAsyncReader(...)` over sync `OpenReader(...)`. +- For async write scenarios, prefer `WriterFactory.OpenAsyncWriter(...)` over sync `OpenWriter(...)`. - Key async methods: - `WriteEntryToAsync` - Extract entry asynchronously - `WriteAllToDirectoryAsync` - Extract all entries asynchronously @@ -199,7 +205,8 @@ SharpCompress supports multiple archive and compression formats: ## Common Pitfalls 1. **Don't mix Archive and Reader APIs** - Archive needs seekable stream, Reader doesn't -2. **Solid archives (Rar, 7Zip)** - Use `ExtractAllEntries()` for best performance, not individual entry extraction -3. **Stream disposal** - Always set `LeaveStreamOpen` explicitly when needed (default is to close) -4. **Tar + non-seekable stream** - Must provide file size or it will throw -5. **Format detection** - Use `ReaderFactory.OpenReader()` for auto-detection, test with actual archive files +2. **Don't mix sync and async open paths** - For async workflows use `OpenAsyncArchive`/`OpenAsyncReader`/`OpenAsyncWriter`, not `OpenArchive`/`OpenReader`/`OpenWriter` +3. **Solid archives (Rar, 7Zip)** - Use `ExtractAllEntries()` for best performance, not individual entry extraction +4. **Stream disposal** - Always set `LeaveStreamOpen` explicitly when needed (default is to close) +5. **Tar + non-seekable stream** - Must provide file size or it will throw +6. **Format detection** - Use `ReaderFactory.OpenReader()` / `ReaderFactory.OpenAsyncReader()` for auto-detection, test with actual archive files diff --git a/tests/SharpCompress.Performance/Benchmarks/GZipBenchmarks.cs b/tests/SharpCompress.Performance/Benchmarks/GZipBenchmarks.cs index 2167e034d..e98040091 100644 --- a/tests/SharpCompress.Performance/Benchmarks/GZipBenchmarks.cs +++ b/tests/SharpCompress.Performance/Benchmarks/GZipBenchmarks.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using SharpCompress.Compressors; using SharpCompress.Compressors.Deflate; @@ -36,6 +37,14 @@ public void GZipCompress() gzipStream.Write(_sourceData, 0, _sourceData.Length); } + [Benchmark(Description = "GZip: Compress 100KB (Async)")] + public async Task GZipCompressAsync() + { + using var outputStream = new MemoryStream(); + using var gzipStream = new GZipStream(outputStream, CompressionMode.Compress); + await gzipStream.WriteAsync(_sourceData, 0, _sourceData.Length).ConfigureAwait(false); + } + [Benchmark(Description = "GZip: Decompress 100KB")] public void GZipDecompress() { @@ -43,4 +52,12 @@ public void GZipDecompress() using var gzipStream = new GZipStream(inputStream, CompressionMode.Decompress); gzipStream.CopyTo(Stream.Null); } + + [Benchmark(Description = "GZip: Decompress 100KB (Async)")] + public async Task GZipDecompressAsync() + { + using var inputStream = new MemoryStream(_compressedData); + using var gzipStream = new GZipStream(inputStream, CompressionMode.Decompress); + await gzipStream.CopyToAsync(Stream.Null).ConfigureAwait(false); + } } diff --git a/tests/SharpCompress.Performance/Benchmarks/RarBenchmarks.cs b/tests/SharpCompress.Performance/Benchmarks/RarBenchmarks.cs index 7a2d6709f..4667694b4 100644 --- a/tests/SharpCompress.Performance/Benchmarks/RarBenchmarks.cs +++ b/tests/SharpCompress.Performance/Benchmarks/RarBenchmarks.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using SharpCompress.Archives.Rar; using SharpCompress.Readers; @@ -30,6 +31,18 @@ public void RarExtractArchiveApi() } } + [Benchmark(Description = "Rar: Extract all entries (Archive API, Async)")] + public async Task RarExtractArchiveApiAsync() + { + using var stream = new MemoryStream(_rarBytes); + await using var archive = RarArchive.OpenAsyncArchive(stream); + await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory)) + { + await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false); + await entryStream.CopyToAsync(Stream.Null).ConfigureAwait(false); + } + } + [Benchmark(Description = "Rar: Extract all entries (Reader API)")] public void RarExtractReaderApi() { @@ -43,4 +56,18 @@ public void RarExtractReaderApi() } } } + + [Benchmark(Description = "Rar: Extract all entries (Reader API, Async)")] + public async Task RarExtractReaderApiAsync() + { + using var stream = new MemoryStream(_rarBytes); + await using var reader = await ReaderFactory.OpenAsyncReader(stream).ConfigureAwait(false); + while (await reader.MoveToNextEntryAsync().ConfigureAwait(false)) + { + if (!reader.Entry.IsDirectory) + { + await reader.WriteEntryToAsync(Stream.Null).ConfigureAwait(false); + } + } + } } diff --git a/tests/SharpCompress.Performance/Benchmarks/SevenZipBenchmarks.cs b/tests/SharpCompress.Performance/Benchmarks/SevenZipBenchmarks.cs index 74fdc5841..8a249b007 100644 --- a/tests/SharpCompress.Performance/Benchmarks/SevenZipBenchmarks.cs +++ b/tests/SharpCompress.Performance/Benchmarks/SevenZipBenchmarks.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using SharpCompress.Archives.SevenZip; @@ -31,6 +32,18 @@ public void SevenZipLzmaExtract() } } + [Benchmark(Description = "7Zip LZMA: Extract all entries (Async)")] + public async Task SevenZipLzmaExtractAsync() + { + using var stream = new MemoryStream(_lzmaBytes); + await using var archive = SevenZipArchive.OpenAsyncArchive(stream); + await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory)) + { + await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false); + await entryStream.CopyToAsync(Stream.Null).ConfigureAwait(false); + } + } + [Benchmark(Description = "7Zip LZMA2: Extract all entries")] public void SevenZipLzma2Extract() { @@ -42,4 +55,42 @@ public void SevenZipLzma2Extract() entryStream.CopyTo(Stream.Null); } } + + [Benchmark(Description = "7Zip LZMA2: Extract all entries (Async)")] + public async Task SevenZipLzma2ExtractAsync() + { + using var stream = new MemoryStream(_lzma2Bytes); + await using var archive = SevenZipArchive.OpenAsyncArchive(stream); + await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory)) + { + await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false); + await entryStream.CopyToAsync(Stream.Null).ConfigureAwait(false); + } + } + + [Benchmark(Description = "7Zip LZMA2 Reader: Extract all entries")] + public void SevenZipLzma2Extract_Reader() + { + using var stream = new MemoryStream(_lzma2Bytes); + using var archive = SevenZipArchive.OpenArchive(stream); + using var reader = archive.ExtractAllEntries(); + foreach (var entry in archive.Entries.Where(e => !e.IsDirectory)) + { + using var entryStream = entry.OpenEntryStream(); + entryStream.CopyTo(Stream.Null); + } + } + + [Benchmark(Description = "7Zip LZMA2 Reader: Extract all entries (Async)")] + public async Task SevenZipLzma2ExtractAsync_Reader() + { + using var stream = new MemoryStream(_lzma2Bytes); + await using var archive = SevenZipArchive.OpenAsyncArchive(stream); + await using var reader = await archive.ExtractAllEntriesAsync(); + while (await reader.MoveToNextEntryAsync().ConfigureAwait(false)) + { + await using var entryStream = await reader.OpenEntryStreamAsync().ConfigureAwait(false); + await entryStream.CopyToAsync(Stream.Null).ConfigureAwait(false); + } + } } diff --git a/tests/SharpCompress.Performance/Benchmarks/TarBenchmarks.cs b/tests/SharpCompress.Performance/Benchmarks/TarBenchmarks.cs index 39d1d97d7..f7ad19e94 100644 --- a/tests/SharpCompress.Performance/Benchmarks/TarBenchmarks.cs +++ b/tests/SharpCompress.Performance/Benchmarks/TarBenchmarks.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using SharpCompress.Archives.Tar; using SharpCompress.Common; @@ -34,6 +35,18 @@ public void TarExtractArchiveApi() } } + [Benchmark(Description = "Tar: Extract all entries (Archive API, Async)")] + public async Task TarExtractArchiveApiAsync() + { + using var stream = new MemoryStream(_tarBytes); + await using var archive = TarArchive.OpenAsyncArchive(stream); + await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory)) + { + await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false); + await entryStream.CopyToAsync(Stream.Null).ConfigureAwait(false); + } + } + [Benchmark(Description = "Tar: Extract all entries (Reader API)")] public void TarExtractReaderApi() { @@ -48,6 +61,20 @@ public void TarExtractReaderApi() } } + [Benchmark(Description = "Tar: Extract all entries (Reader API, Async)")] + public async Task TarExtractReaderApiAsync() + { + using var stream = new MemoryStream(_tarBytes); + await using var reader = await ReaderFactory.OpenAsyncReader(stream).ConfigureAwait(false); + while (await reader.MoveToNextEntryAsync().ConfigureAwait(false)) + { + if (!reader.Entry.IsDirectory) + { + await reader.WriteEntryToAsync(Stream.Null).ConfigureAwait(false); + } + } + } + [Benchmark(Description = "Tar.GZip: Extract all entries")] public void TarGzipExtract() { @@ -60,6 +87,18 @@ public void TarGzipExtract() } } + [Benchmark(Description = "Tar.GZip: Extract all entries (Async)")] + public async Task TarGzipExtractAsync() + { + using var stream = new MemoryStream(_tarGzBytes); + await using var archive = TarArchive.OpenAsyncArchive(stream); + await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory)) + { + await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false); + await entryStream.CopyToAsync(Stream.Null).ConfigureAwait(false); + } + } + [Benchmark(Description = "Tar: Create archive with small files")] public void TarCreateSmallFiles() { @@ -78,4 +117,22 @@ public void TarCreateSmallFiles() writer.Write($"file{i}.txt", entryStream); } } + + [Benchmark(Description = "Tar: Create archive with small files (Async)")] + public async Task TarCreateSmallFilesAsync() + { + using var outputStream = new MemoryStream(); + await using var writer = WriterFactory.OpenAsyncWriter( + outputStream, + ArchiveType.Tar, + new WriterOptions(CompressionType.None) { LeaveStreamOpen = true } + ); + + for (int i = 0; i < 10; i++) + { + var data = new byte[1024]; + using var entryStream = new MemoryStream(data); + await writer.WriteAsync($"file{i}.txt", entryStream).ConfigureAwait(false); + } + } } diff --git a/tests/SharpCompress.Performance/Benchmarks/ZipBenchmarks.cs b/tests/SharpCompress.Performance/Benchmarks/ZipBenchmarks.cs index 00e58a0e5..fb95d0187 100644 --- a/tests/SharpCompress.Performance/Benchmarks/ZipBenchmarks.cs +++ b/tests/SharpCompress.Performance/Benchmarks/ZipBenchmarks.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using SharpCompress.Archives.Zip; using SharpCompress.Common; @@ -34,6 +35,18 @@ public void ZipExtractArchiveApi() } } + [Benchmark(Description = "Zip: Extract all entries (Archive API, Async)")] + public async Task ZipExtractArchiveApiAsync() + { + using var stream = new MemoryStream(_archiveBytes); + await using var archive = ZipArchive.OpenAsyncArchive(stream); + await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory)) + { + await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false); + await entryStream.CopyToAsync(Stream.Null).ConfigureAwait(false); + } + } + [Benchmark(Description = "Zip: Extract all entries (Reader API)")] public void ZipExtractReaderApi() { @@ -48,6 +61,20 @@ public void ZipExtractReaderApi() } } + [Benchmark(Description = "Zip: Extract all entries (Reader API, Async)")] + public async Task ZipExtractReaderApiAsync() + { + using var stream = new MemoryStream(_archiveBytes); + await using var reader = await ReaderFactory.OpenAsyncReader(stream).ConfigureAwait(false); + while (await reader.MoveToNextEntryAsync().ConfigureAwait(false)) + { + if (!reader.Entry.IsDirectory) + { + await reader.WriteEntryToAsync(Stream.Null).ConfigureAwait(false); + } + } + } + [Benchmark(Description = "Zip: Create archive with small files")] public void ZipCreateSmallFiles() { @@ -66,4 +93,22 @@ public void ZipCreateSmallFiles() writer.Write($"file{i}.txt", entryStream); } } + + [Benchmark(Description = "Zip: Create archive with small files (Async)")] + public async Task ZipCreateSmallFilesAsync() + { + using var outputStream = new MemoryStream(); + await using var writer = WriterFactory.OpenAsyncWriter( + outputStream, + ArchiveType.Zip, + new WriterOptions(CompressionType.Deflate) { LeaveStreamOpen = true } + ); + + for (int i = 0; i < 10; i++) + { + var data = new byte[1024]; + using var entryStream = new MemoryStream(data); + await writer.WriteAsync($"file{i}.txt", entryStream).ConfigureAwait(false); + } + } } diff --git a/tests/SharpCompress.Performance/Program.cs b/tests/SharpCompress.Performance/Program.cs index 75d4b16b6..35e257b8a 100644 --- a/tests/SharpCompress.Performance/Program.cs +++ b/tests/SharpCompress.Performance/Program.cs @@ -20,10 +20,10 @@ public static void Main(string[] args) // Default: Run BenchmarkDotNet var config = DefaultConfig.Instance.AddJob( Job.Default.WithToolchain(InProcessEmitToolchain.Instance) - .WithWarmupCount(3) // Minimal warmup iterations for CI - .WithIterationCount(10) // Minimal measurement iterations for CI - .WithInvocationCount(10) - .WithUnrollFactor(1) + .WithWarmupCount(5) // Minimal warmup iterations for CI + .WithIterationCount(30) // Minimal measurement iterations for CI + .WithInvocationCount(30) + .WithUnrollFactor(2) ); BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config); diff --git a/tests/SharpCompress.Performance/README.md b/tests/SharpCompress.Performance/README.md index 91ebfb33f..43e9df9e1 100644 --- a/tests/SharpCompress.Performance/README.md +++ b/tests/SharpCompress.Performance/README.md @@ -5,11 +5,11 @@ This project contains performance benchmarks for SharpCompress using [BenchmarkD ## Overview The benchmarks test all major archive formats supported by SharpCompress: -- **Zip**: Read (Archive & Reader API) and Write operations -- **Tar**: Read (Archive & Reader API) and Write operations, including Tar.GZip -- **Rar**: Read operations (Archive & Reader API) -- **7Zip**: Read operations for LZMA and LZMA2 compression -- **GZip**: Compression and decompression +- **Zip**: Read (Archive & Reader API) and Write operations, each with sync and async variants +- **Tar**: Read (Archive & Reader API) and Write operations, including Tar.GZip, each with sync and async variants +- **Rar**: Read operations (Archive & Reader API), each with sync and async variants +- **7Zip**: Read operations for LZMA and LZMA2 compression, each with sync and async variants +- **GZip**: Compression and decompression, each with sync and async variants ## Running Benchmarks diff --git a/tests/SharpCompress.Performance/baseline-results.md b/tests/SharpCompress.Performance/baseline-results.md index 479a7deb3..6d9874a1b 100644 --- a/tests/SharpCompress.Performance/baseline-results.md +++ b/tests/SharpCompress.Performance/baseline-results.md @@ -1,23 +1,49 @@ -| Method | Mean | Error | StdDev | Allocated | -|------------------------- |-----------:|---------:|---------:|----------:| -| 'GZip: Compress 100KB' | 3,268.7 μs | 28.50 μs | 16.96 μs | 519.2 KB | -| 'GZip: Decompress 100KB' | 436.6 μs | 3.23 μs | 1.69 μs | 34.18 KB | -| Method | Mean | Error | StdDev | Allocated | -|----------------------------------------- |---------:|----------:|----------:|----------:| -| 'Rar: Extract all entries (Archive API)' | 2.054 ms | 0.3927 ms | 0.2598 ms | 91.09 KB | -| 'Rar: Extract all entries (Reader API)' | 2.235 ms | 0.0253 ms | 0.0132 ms | 149.48 KB | -| Method | Mean | Error | StdDev | Allocated | -|---------------------------------- |---------:|----------:|----------:|----------:| -| '7Zip LZMA: Extract all entries' | 9.124 ms | 2.1930 ms | 1.4505 ms | 272.8 KB | -| '7Zip LZMA2: Extract all entries' | 7.810 ms | 0.1323 ms | 0.0788 ms | 272.58 KB | -| Method | Mean | Error | StdDev | Allocated | -|----------------------------------------- |----------:|---------:|---------:|----------:| -| 'Tar: Extract all entries (Archive API)' | 56.36 μs | 3.312 μs | 1.971 μs | 16.65 KB | -| 'Tar: Extract all entries (Reader API)' | 175.34 μs | 2.616 μs | 1.557 μs | 213.36 KB | -| 'Tar.GZip: Extract all entries' | NA | NA | NA | NA | -| 'Tar: Create archive with small files' | 51.38 μs | 2.349 μs | 1.398 μs | 68.7 KB | -| Method | Mean | Error | StdDev | Gen0 | Allocated | -|----------------------------------------- |-----------:|---------:|---------:|---------:|-----------:| -| 'Zip: Extract all entries (Archive API)' | 1,188.4 μs | 28.62 μs | 14.97 μs | - | 181.66 KB | -| 'Zip: Extract all entries (Reader API)' | 1,137.0 μs | 5.58 μs | 2.92 μs | - | 123.19 KB | -| 'Zip: Create archive with small files' | 258.2 μs | 8.98 μs | 4.70 μs | 100.0000 | 2806.93 KB | \ No newline at end of file +| Method | Mean | Error | StdDev | Allocated | +|---------------------------- |---------:|---------:|---------:|----------:| +| SharpCompress_0_44_Original | 581.8 ms | 11.56 ms | 17.65 ms | 48.77 MB | +| Method | Mean | Error | StdDev | Median | Gen0 | Gen1 | Gen2 | Allocated | +|-------------------- |-----------:|----------:|----------:|-----------:|---------:|---------:|---------:|----------:| +| ZipArchiveRead | 959.2 μs | 52.16 μs | 153.78 μs | 928.7 μs | 27.3438 | 5.8594 | - | 345.75 KB | +| TarArchiveRead | 252.1 μs | 20.97 μs | 61.82 μs | 251.9 μs | 12.2070 | 5.8594 | - | 154.78 KB | +| TarGzArchiveRead | 600.9 μs | 19.25 μs | 53.98 μs | 607.8 μs | 16.6016 | 6.8359 | - | 204.95 KB | +| TarBz2ArchiveRead | NA | NA | NA | NA | NA | NA | NA | NA | +| SevenZipArchiveRead | 8,354.4 μs | 273.01 μs | 747.35 μs | 8,093.2 μs | 109.3750 | 109.3750 | 109.3750 | 787.99 KB | +| RarArchiveRead | 1,648.6 μs | 131.91 μs | 388.94 μs | 1,617.6 μs | 17.5781 | 5.8594 | - | 222.62 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|--------------------------------- |-----------:|--------:|---------:|--------:|--------:|--------:|----------:| +| 'GZip: Compress 100KB' | 3,317.1 μs | 7.15 μs | 10.02 μs | 33.3333 | 33.3333 | 33.3333 | 519.31 KB | +| 'GZip: Compress 100KB (Async)' | 3,280.3 μs | 8.30 μs | 11.63 μs | 33.3333 | 33.3333 | 33.3333 | 519.46 KB | +| 'GZip: Decompress 100KB' | 432.5 μs | 2.43 μs | 3.56 μs | - | - | - | 33.92 KB | +| 'GZip: Decompress 100KB (Async)' | 442.8 μs | 1.20 μs | 1.76 μs | - | - | - | 34.24 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|------------------------------------------------ |-----------:|----------:|----------:|---------:|---------:|---------:|-----------:| +| 'Rar: Extract all entries (Archive API)' | 908.2 μs | 12.42 μs | 17.01 μs | - | - | - | 90.68 KB | +| 'Rar: Extract all entries (Archive API, Async)' | 1,175.4 μs | 118.74 μs | 177.72 μs | - | - | - | 96.09 KB | +| 'Rar: Extract all entries (Reader API)' | 1,215.1 μs | 2.26 μs | 3.09 μs | - | - | - | 148.85 KB | +| 'Rar: Extract all entries (Reader API, Async)' | 1,592.0 μs | 22.58 μs | 33.10 μs | 500.0000 | 500.0000 | 500.0000 | 4776.76 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|------------------------------------------------- |----------:|----------:|----------:|---------:|---------:|---------:|-----------:| +| '7Zip LZMA: Extract all entries' | 7.723 ms | 0.0111 ms | 0.0152 ms | 33.3333 | 33.3333 | 33.3333 | 272.68 KB | +| '7Zip LZMA: Extract all entries (Async)' | 35.827 ms | 0.0381 ms | 0.0546 ms | 200.0000 | 33.3333 | 33.3333 | 3402.82 KB | +| '7Zip LZMA2: Extract all entries' | 7.758 ms | 0.0074 ms | 0.0104 ms | 33.3333 | 33.3333 | 33.3333 | 272.46 KB | +| '7Zip LZMA2: Extract all entries (Async)' | 36.317 ms | 0.0345 ms | 0.0506 ms | 200.0000 | 33.3333 | 33.3333 | 3409.72 KB | +| '7Zip LZMA2 Reader: Extract all entries' | 7.706 ms | 0.0114 ms | 0.0163 ms | 33.3333 | 33.3333 | 33.3333 | 273.03 KB | +| '7Zip LZMA2 Reader: Extract all entries (Async)' | 22.951 ms | 0.0973 ms | 0.1426 ms | 100.0000 | 100.0000 | 100.0000 | 2420.81 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|------------------------------------------------ |----------:|---------:|---------:|--------:|--------:|--------:|----------:| +| 'Tar: Extract all entries (Archive API)' | 40.82 μs | 0.292 μs | 0.427 μs | - | - | - | 16.36 KB | +| 'Tar: Extract all entries (Archive API, Async)' | 105.12 μs | 6.183 μs | 9.254 μs | - | - | - | 14.57 KB | +| 'Tar: Extract all entries (Reader API)' | 187.89 μs | 1.571 μs | 2.254 μs | 66.6667 | 66.6667 | 66.6667 | 341.24 KB | +| 'Tar: Extract all entries (Reader API, Async)' | 229.78 μs | 4.852 μs | 6.802 μs | 66.6667 | 66.6667 | 66.6667 | 376.64 KB | +| 'Tar.GZip: Extract all entries' | NA | NA | NA | NA | NA | NA | NA | +| 'Tar.GZip: Extract all entries (Async)' | NA | NA | NA | NA | NA | NA | NA | +| 'Tar: Create archive with small files' | 46.98 μs | 0.287 μs | 0.394 μs | - | - | - | 68.11 KB | +| 'Tar: Create archive with small files (Async)' | 53.14 μs | 0.352 μs | 0.493 μs | - | - | - | 68.11 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | +|------------------------------------------------ |---------:|---------:|---------:|---------:|--------:|-----------:| +| 'Zip: Extract all entries (Archive API)' | 556.7 μs | 3.38 μs | 4.74 μs | - | - | 180.22 KB | +| 'Zip: Extract all entries (Archive API, Async)' | 615.7 μs | 15.98 μs | 22.92 μs | - | - | 125.52 KB | +| 'Zip: Extract all entries (Reader API)' | 542.2 μs | 1.10 μs | 1.46 μs | - | - | 121.04 KB | +| 'Zip: Extract all entries (Reader API, Async)' | 562.8 μs | 2.42 μs | 3.55 μs | - | - | 123.34 KB | +| 'Zip: Create archive with small files' | 271.1 μs | 12.93 μs | 18.95 μs | 166.6667 | 33.3333 | 2806.28 KB | +| 'Zip: Create archive with small files (Async)' | 394.3 μs | 25.59 μs | 36.71 μs | 166.6667 | 33.3333 | 2811.42 KB | \ No newline at end of file