From c08670f20824d33604cdf53eadac871292a5fe62 Mon Sep 17 00:00:00 2001 From: carlossanlop <1175054+carlossanlop@users.noreply.github.com> Date: Thu, 9 Mar 2023 13:37:18 -0600 Subject: [PATCH 1/8] Micro benchmarks for System.Formats.Tar.TarWriter.WriteEntry --- .../libraries/System.Formats.Tar/Perf.Tar.cs | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs diff --git a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs new file mode 100644 index 00000000000..6ee9c1f2119 --- /dev/null +++ b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs @@ -0,0 +1,111 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using MicroBenchmarks; + +namespace System.Formats.Tar.Tests +{ + [BenchmarkCategory(Categories.Libraries, Categories.NoWASM)] + public class Perf_TarWriter + { + private static readonly string _fileName = "file.txt"; + private static Dictionary _ea; + private static MemoryStream _memoryStream; + + [GlobalSetup] + public void Setup() + { + _memoryStream = new MemoryStream(); + } + + [GlobalCleanup] + public void Cleanup() => _memoryStream.Dispose(); + + [GlobalSetup(Targets = new[] { nameof(PaxTarEntry_WriteEntry), nameof(PaxTarEntry_WriteEntry_Async) })] + public void SetupPax() + { + _ea = new Dictionary + { + { "uname", "username" }, + { "gname", "groupname" }, + { "uid", "483745" }, + { "gid", "193783" }, + { "mtime", "1409547224" }, + { "ctime", "1409547225" }, + { "atime", "1409547226" }, + // real world scenario: + { "MSWINDOWS.rawsd", "AQAAgBQAAAAkAAAAAAAAAAAAAAABAgAAAAAABSAAAAAhAgAAAQIAAAAAAAUgAAAAIQIAAA==" } + }; + } + + [Benchmark] + public void V7TarEntry_WriteEntry() + { + V7TarEntry entry = new V7TarEntry(TarEntryType.RegularFile, _fileName); + using TarWriter writer = new TarWriter(_memoryStream); + writer.WriteEntry(entry); + } + + [Benchmark] + public async Task V7TarEntry_WriteEntry_Async() + { + V7TarEntry entry = new V7TarEntry(TarEntryType.RegularFile, _fileName); + await using TarWriter writer = new TarWriter(_memoryStream); + await writer.WriteEntryAsync(entry); + } + + [Benchmark] + public void UstarTarEntry_WriteEntry() + { + UstarTarEntry entry = new UstarTarEntry(TarEntryType.RegularFile, _fileName); + using TarWriter writer = new TarWriter(_memoryStream); + writer.WriteEntry(entry); + } + + [Benchmark] + public async Task UstarTarEntry_WriteEntry_Async() + { + UstarTarEntry entry = new UstarTarEntry(TarEntryType.RegularFile, _fileName); + await using TarWriter writer = new TarWriter(_memoryStream); + await writer.WriteEntryAsync(entry); + } + + [Benchmark] + public void PaxTarEntry_WriteEntry() + { + PaxTarEntry entry = new PaxTarEntry(TarEntryType.RegularFile, _fileName, _ea); + using TarWriter writer = new TarWriter(_memoryStream); + writer.WriteEntry(entry); + } + + [Benchmark] + public async Task PaxTarEntry_WriteEntry_Async() + { + PaxTarEntry entry = new PaxTarEntry(TarEntryType.RegularFile, _fileName, _ea); + await using TarWriter writer = new TarWriter(_memoryStream); + await writer.WriteEntryAsync(entry); + } + + [Benchmark] + public void GnuTarEntry_WriteEntry() + { + GnuTarEntry entry = new GnuTarEntry(TarEntryType.RegularFile, _fileName); + using TarWriter writer = new TarWriter(_memoryStream); + writer.WriteEntry(entry); + } + + [Benchmark] + public async Task GnuTarEntry_WriteEntry_Async() + { + GnuTarEntry entry = new GnuTarEntry(TarEntryType.RegularFile, _fileName); + await using TarWriter writer = new TarWriter(_memoryStream); + await writer.WriteEntryAsync(entry); + } + + } +} \ No newline at end of file From 08ebd32e8f04de74e856fb011d93d9cc102c8b01 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Mon, 22 May 2023 14:04:03 +0200 Subject: [PATCH 2/8] Apply suggestions from code review --- .../libraries/System.Formats.Tar/Perf.Tar.cs | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs index 6ee9c1f2119..f1778776598 100644 --- a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs +++ b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs @@ -47,7 +47,7 @@ public void SetupPax() public void V7TarEntry_WriteEntry() { V7TarEntry entry = new V7TarEntry(TarEntryType.RegularFile, _fileName); - using TarWriter writer = new TarWriter(_memoryStream); + using TarWriter writer = CreateWriter(); writer.WriteEntry(entry); } @@ -55,7 +55,7 @@ public void V7TarEntry_WriteEntry() public async Task V7TarEntry_WriteEntry_Async() { V7TarEntry entry = new V7TarEntry(TarEntryType.RegularFile, _fileName); - await using TarWriter writer = new TarWriter(_memoryStream); + await using TarWriter writer = CreateWriter(); await writer.WriteEntryAsync(entry); } @@ -63,7 +63,7 @@ public async Task V7TarEntry_WriteEntry_Async() public void UstarTarEntry_WriteEntry() { UstarTarEntry entry = new UstarTarEntry(TarEntryType.RegularFile, _fileName); - using TarWriter writer = new TarWriter(_memoryStream); + using TarWriter writer = CreateWriter(); writer.WriteEntry(entry); } @@ -71,7 +71,7 @@ public void UstarTarEntry_WriteEntry() public async Task UstarTarEntry_WriteEntry_Async() { UstarTarEntry entry = new UstarTarEntry(TarEntryType.RegularFile, _fileName); - await using TarWriter writer = new TarWriter(_memoryStream); + await using TarWriter writer = CreateWriter(); await writer.WriteEntryAsync(entry); } @@ -79,7 +79,7 @@ public async Task UstarTarEntry_WriteEntry_Async() public void PaxTarEntry_WriteEntry() { PaxTarEntry entry = new PaxTarEntry(TarEntryType.RegularFile, _fileName, _ea); - using TarWriter writer = new TarWriter(_memoryStream); + using TarWriter writer = CreateWriter(); writer.WriteEntry(entry); } @@ -87,7 +87,7 @@ public void PaxTarEntry_WriteEntry() public async Task PaxTarEntry_WriteEntry_Async() { PaxTarEntry entry = new PaxTarEntry(TarEntryType.RegularFile, _fileName, _ea); - await using TarWriter writer = new TarWriter(_memoryStream); + await using TarWriter writer = CreateWriter(); await writer.WriteEntryAsync(entry); } @@ -95,7 +95,7 @@ public async Task PaxTarEntry_WriteEntry_Async() public void GnuTarEntry_WriteEntry() { GnuTarEntry entry = new GnuTarEntry(TarEntryType.RegularFile, _fileName); - using TarWriter writer = new TarWriter(_memoryStream); + using TarWriter writer = CreateWriter(); writer.WriteEntry(entry); } @@ -103,9 +103,17 @@ public void GnuTarEntry_WriteEntry() public async Task GnuTarEntry_WriteEntry_Async() { GnuTarEntry entry = new GnuTarEntry(TarEntryType.RegularFile, _fileName); - await using TarWriter writer = new TarWriter(_memoryStream); + await using TarWriter writer = CreateWriter(); await writer.WriteEntryAsync(entry); } + private TarWriter CreateWriter() + { + // BDN runs every benchmark more than once, so we want to reuse the memory stream instance + // and have it always perform the same amount of work. + _memoryStream.Position = 0; + return new TarWriter(_memoryStream, leaveOpen: true); + } + } } \ No newline at end of file From eaec9ef8448a776bcd098de0329b92058470ed28 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Mon, 22 May 2023 14:04:31 +0200 Subject: [PATCH 3/8] Apply suggestions from code review --- src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs index f1778776598..e1f0ac18f6b 100644 --- a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs +++ b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs @@ -114,6 +114,5 @@ private TarWriter CreateWriter() _memoryStream.Position = 0; return new TarWriter(_memoryStream, leaveOpen: true); } - } } \ No newline at end of file From c8be621691d5573229fae3acb46fd04020999188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 22 May 2023 18:56:05 -0700 Subject: [PATCH 4/8] Remove unnecessary Dispose of MemoryStream. --- src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs index e1f0ac18f6b..0de27821590 100644 --- a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs +++ b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs @@ -23,9 +23,6 @@ public void Setup() _memoryStream = new MemoryStream(); } - [GlobalCleanup] - public void Cleanup() => _memoryStream.Dispose(); - [GlobalSetup(Targets = new[] { nameof(PaxTarEntry_WriteEntry), nameof(PaxTarEntry_WriteEntry_Async) })] public void SetupPax() { From bb90c25b2d7710919e6e0dbd0d91c22b7d226cf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 22 May 2023 18:56:19 -0700 Subject: [PATCH 5/8] Remove unnecessary using of MemoryStreams. --- .../micro/libraries/System.Formats.Tar/Perf.TarFile.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.TarFile.cs b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.TarFile.cs index 9ca1dc4d4ae..279bb2f3cc7 100644 --- a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.TarFile.cs +++ b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.TarFile.cs @@ -67,15 +67,15 @@ public async Task CreateFromDirectory_Path_Async() [Benchmark] public void CreateFromDirectory_Stream() { - using MemoryStream ms = new MemoryStream(); + MemoryStream ms = new MemoryStream(); TarFile.CreateFromDirectory(sourceDirectoryName: _inputDirPath, destination: ms, includeBaseDirectory: false); } [Benchmark] - public async Task CreateFromDirectory_Stream_Async() + public Task CreateFromDirectory_Stream_Async() { - await using MemoryStream ms = new MemoryStream(); - await TarFile.CreateFromDirectoryAsync(sourceDirectoryName: _inputDirPath, destination: ms, includeBaseDirectory: false); + MemoryStream ms = new MemoryStream(); + return TarFile.CreateFromDirectoryAsync(sourceDirectoryName: _inputDirPath, destination: ms, includeBaseDirectory: false); } [Benchmark] From 2a6d44de2db214d332cca0811dc1c8a94a846f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 22 May 2023 19:00:32 -0700 Subject: [PATCH 6/8] Fix V7 failures. --- src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs index 0de27821590..93f7dffdcc1 100644 --- a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs +++ b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs @@ -43,7 +43,7 @@ public void SetupPax() [Benchmark] public void V7TarEntry_WriteEntry() { - V7TarEntry entry = new V7TarEntry(TarEntryType.RegularFile, _fileName); + V7TarEntry entry = new V7TarEntry(TarEntryType.V7RegularFile, _fileName); using TarWriter writer = CreateWriter(); writer.WriteEntry(entry); } @@ -51,7 +51,7 @@ public void V7TarEntry_WriteEntry() [Benchmark] public async Task V7TarEntry_WriteEntry_Async() { - V7TarEntry entry = new V7TarEntry(TarEntryType.RegularFile, _fileName); + V7TarEntry entry = new V7TarEntry(TarEntryType.V7RegularFile, _fileName); await using TarWriter writer = CreateWriter(); await writer.WriteEntryAsync(entry); } From 94626f3a0fafb1d3201c072c57f35504c86b23ac Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Tue, 23 May 2023 08:26:01 +0200 Subject: [PATCH 7/8] Apply suggestions from code review --- .../micro/libraries/System.Formats.Tar/Perf.Tar.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs index 93f7dffdcc1..7cabcd0d6be 100644 --- a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs +++ b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.Tar.cs @@ -14,18 +14,20 @@ namespace System.Formats.Tar.Tests public class Perf_TarWriter { private static readonly string _fileName = "file.txt"; - private static Dictionary _ea; - private static MemoryStream _memoryStream; + private Dictionary _ea; + private MemoryStream _memoryStream; [GlobalSetup] - public void Setup() - { - _memoryStream = new MemoryStream(); - } + public void Setup() => _memoryStream = new MemoryStream(); + + [GlobalCleanup] + public void Cleanup() => _memoryStream.Dispose(); [GlobalSetup(Targets = new[] { nameof(PaxTarEntry_WriteEntry), nameof(PaxTarEntry_WriteEntry_Async) })] public void SetupPax() { + Setup(); + _ea = new Dictionary { { "uname", "username" }, From c3ea371904d69515d4449b660c46fe7c28c1e165 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Tue, 23 May 2023 08:28:02 +0200 Subject: [PATCH 8/8] Apply suggestions from code review --- .../micro/libraries/System.Formats.Tar/Perf.TarFile.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.TarFile.cs b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.TarFile.cs index 279bb2f3cc7..9ca1dc4d4ae 100644 --- a/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.TarFile.cs +++ b/src/benchmarks/micro/libraries/System.Formats.Tar/Perf.TarFile.cs @@ -67,15 +67,15 @@ public async Task CreateFromDirectory_Path_Async() [Benchmark] public void CreateFromDirectory_Stream() { - MemoryStream ms = new MemoryStream(); + using MemoryStream ms = new MemoryStream(); TarFile.CreateFromDirectory(sourceDirectoryName: _inputDirPath, destination: ms, includeBaseDirectory: false); } [Benchmark] - public Task CreateFromDirectory_Stream_Async() + public async Task CreateFromDirectory_Stream_Async() { - MemoryStream ms = new MemoryStream(); - return TarFile.CreateFromDirectoryAsync(sourceDirectoryName: _inputDirPath, destination: ms, includeBaseDirectory: false); + await using MemoryStream ms = new MemoryStream(); + await TarFile.CreateFromDirectoryAsync(sourceDirectoryName: _inputDirPath, destination: ms, includeBaseDirectory: false); } [Benchmark]