From 0d76ecc72f207748321130f60351e452d88064a6 Mon Sep 17 00:00:00 2001 From: xtqqczze Date: Thu, 13 Aug 2020 00:05:11 +0100 Subject: [PATCH 1/5] Use StringBuilder in loop --- .../PdhHelper.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs index 130a7f41804..25ddb42945c 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs @@ -9,7 +9,7 @@ using System.Globalization; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; - +using System.Text; using Microsoft.PowerShell.Commands.GetCounter; using Microsoft.Win32; @@ -542,15 +542,16 @@ public uint ConnectToDataSource(StringCollection blgFileNames) return ConnectToDataSource(blgFileNames[0]); } - string doubleNullTerminated = string.Empty; - foreach (string fileName in blgFileNames) + StringBuilder doubleNullTerminated = new StringBuilder(); + for (int i = 0; i < blgFileNames.Count; i++) { - doubleNullTerminated += fileName + '\0'; + string fileName = blgFileNames[i]; + doubleNullTerminated.Append(fileName).Append('\0'); } - doubleNullTerminated += '\0'; + doubleNullTerminated.Append('\0'); - return ConnectToDataSource(doubleNullTerminated); + return ConnectToDataSource(doubleNullTerminated.ToString()); } public uint OpenQuery() From e267df2a4744cefe01336d79b995a7ab86ecaf1e Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Fri, 14 Aug 2020 01:46:30 +0100 Subject: [PATCH 2/5] Use List instead of StringCollection --- src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs index 25ddb42945c..ab7a7086953 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs @@ -535,7 +535,7 @@ public uint ConnectToDataSource(string dataSourceName) return res; } - public uint ConnectToDataSource(StringCollection blgFileNames) + public uint ConnectToDataSource(List blgFileNames) { if (blgFileNames.Count == 1) { From b3de86160fbb509fa8035fdd6507268921daaffe Mon Sep 17 00:00:00 2001 From: xtqqczze Date: Sun, 16 Aug 2020 19:29:25 +0100 Subject: [PATCH 3/5] Calculate StringBuilder capacity upfront --- .../PdhHelper.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs index ab7a7086953..faccb436265 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs @@ -542,7 +542,14 @@ public uint ConnectToDataSource(List blgFileNames) return ConnectToDataSource(blgFileNames[0]); } - StringBuilder doubleNullTerminated = new StringBuilder(); + int capacity = blgFileNames.Count + 1; + for (int i = 0; i < blgFileNames.Count; i++) + { + capacity += blgFileNames[i].Length; + } + + StringBuilder doubleNullTerminated = new StringBuilder(capacity); + for (int i = 0; i < blgFileNames.Count; i++) { string fileName = blgFileNames[i]; From 5ba99b7e6d450be17f8b49168f54b5265e84390b Mon Sep 17 00:00:00 2001 From: xtqqczze Date: Sun, 16 Aug 2020 19:47:49 +0100 Subject: [PATCH 4/5] Use Span --- .../PdhHelper.cs | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs index faccb436265..1935c78a7a7 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs @@ -542,21 +542,29 @@ public uint ConnectToDataSource(List blgFileNames) return ConnectToDataSource(blgFileNames[0]); } - int capacity = blgFileNames.Count + 1; + int length = blgFileNames.Count + 1; for (int i = 0; i < blgFileNames.Count; i++) { - capacity += blgFileNames[i].Length; + length += blgFileNames[i].Length; } - StringBuilder doubleNullTerminated = new StringBuilder(capacity); + Span doubleNullTerminated = new char[length]; + int pos = 0; for (int i = 0; i < blgFileNames.Count; i++) { - string fileName = blgFileNames[i]; - doubleNullTerminated.Append(fileName).Append('\0'); + ReadOnlySpan fileName = blgFileNames[i]; + fileName.CopyTo( + doubleNullTerminated.Slice(pos, fileName.Length)); + pos += fileName.Length; + doubleNullTerminated[pos] = '\0'; + pos++; } - doubleNullTerminated.Append('\0'); + doubleNullTerminated[pos] = '\0'; + pos++; + + Debug.Assert(pos == length, "Error constructing double null terminated string."); return ConnectToDataSource(doubleNullTerminated.ToString()); } From 0e363ee676ec3ef5348049319da8a4a22d47ff92 Mon Sep 17 00:00:00 2001 From: xtqqczze Date: Fri, 28 Aug 2020 21:02:25 +0100 Subject: [PATCH 5/5] Use string.Create apply @rjmholt suggestion --- .../PdhHelper.cs | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs index 1935c78a7a7..ea5c19da2e9 100644 --- a/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Diagnostics/PdhHelper.cs @@ -548,25 +548,27 @@ public uint ConnectToDataSource(List blgFileNames) length += blgFileNames[i].Length; } - Span doubleNullTerminated = new char[length]; - - int pos = 0; - for (int i = 0; i < blgFileNames.Count; i++) + string doubleNullTerminated = string.Create(length, blgFileNames, (buf, fileNames) => { - ReadOnlySpan fileName = blgFileNames[i]; - fileName.CopyTo( - doubleNullTerminated.Slice(pos, fileName.Length)); - pos += fileName.Length; - doubleNullTerminated[pos] = '\0'; - pos++; - } + int pos = 0; + for (int i = 0; i < fileNames.Count; i++) + { + string fileName = fileNames[i]; + int fileNameLength = fileName.Length; + fileName.AsSpan().CopyTo( + buf.Slice(pos, fileNameLength)); + pos += fileNameLength; + buf[pos] = '\0'; + pos++; + } - doubleNullTerminated[pos] = '\0'; - pos++; + buf[pos] = '\0'; + pos++; - Debug.Assert(pos == length, "Error constructing double null terminated string."); + Debug.Assert(pos == length, "Error constructing double null terminated string."); + }); - return ConnectToDataSource(doubleNullTerminated.ToString()); + return ConnectToDataSource(doubleNullTerminated); } public uint OpenQuery()