Skip to content

Instantly share code, notes, and snippets.

@santisq
Last active August 27, 2024 23:41
Show Gist options
  • Save santisq/5215221b0e5cc61fd0cf24339a6f1ec8 to your computer and use it in GitHub Desktop.
Save santisq/5215221b0e5cc61fd0cf24339a6f1ec8 to your computer and use it in GitHub Desktop.
Invoke-RestMethod https://gist.githubusercontent.com/santisq/bd3d1d47c89f030be1b4e57b92baaddd/raw/aa78870a9674e9e4769b05e333586bf405c1362c/Measure-Expression.ps1 |
Invoke-Expression
Add-Type @'
using System;
using System.Text;
public static class TestString
{
public static string Create(string @string, int len) =>
string.Create(length: len, state: @string, action: Action);
private static void Action(Span<char> chars, string state)
{
int i = 0; int x = 0;
bool prevSpace = false;
foreach (char e in state.AsSpan())
{
if (i++ == chars.Length)
{
return;
}
if (char.IsWhiteSpace(e))
{
if (!prevSpace)
{
chars[x++] = ' ';
}
prevSpace = true;
continue;
}
chars[x++] = e;
prevSpace = false;
}
}
public static string Builder(string @string, int len)
{
StringBuilder sb = new(len);
bool prevSpace = false;
foreach (char e in @string)
{
if (sb.Length == len)
{
break;
}
if (char.IsWhiteSpace(e))
{
if (!prevSpace)
{
sb.Append(' ');
}
prevSpace = true;
continue;
}
sb.Append(e);
prevSpace = false;
}
return sb.ToString();
}
}
'@
$tests = @{
'Regex Replace + SubString' = {
param([string] $String, [int] $MaxLength)
$Text = $String -Replace '\s+', ' '
if ($Text.Length -gt $MaxLength) {
$Text = $Text.SubString(0, $MaxLength)
}
$Text
}
'StringBuilder' = {
param([string] $String, [int] $MaxLength)
$sb = [System.Text.StringBuilder]::new($MaxLength)
foreach ($char in $String.GetEnumerator()) {
if ($sb.Length -eq $MaxLength) {
break
}
if ([char]::IsWhiteSpace($char)) {
if (-not $prevSpace) {
$sb = $sb.Append(' ')
}
$prevSpace = $true
continue
}
$sb = $sb.Append($char)
$prevSpace = $false
}
$sb.ToString()
}
'StringBuilder (Compiled)' = {
param([string] $String, [int] $MaxLength)
[TestString]::Builder($String, $MaxLength)
}
'String.Create' = {
param([string] $String, [int] $MaxLength)
[TestString]::Create($String, $MaxLength)
}
}
$sb = [System.Text.StringBuilder]::new()
1kb, 10kb, 50kb, 100kb, 500kb | ForEach-Object {
$sb = $sb.Clear()
foreach ($i in 0..$_) {
$sb = $sb.Append('word' + ' ' * (Get-Random -Maximum 10))
}
Measure-Expression $tests -Parameters @{
string = $sb.ToString()
maxlength = 1000
} | Select-Object @{ N='WordCount'; E={ $sb.Length }}, *
} | Format-Table -GroupBy WordCount
using System;
public static class TestString
{
public static string Create(string @string, int len) =>
string.Create(length: len, state: @string, action: Action);
private static void Action(Span<char> chars, string state)
{
int i = 0;
bool prevSpace = false;
foreach (char e in state)
{
if (i == chars.Length)
{
return;
}
if (char.IsWhiteSpace(e))
{
if (!prevSpace)
{
chars[i++] = ' ';
}
prevSpace = true;
continue;
}
chars[i++] = e;
prevSpace = false;
}
}
}
   WordCount: 1024

WordCount Test          Average RelativeSpeed
--------- ----          ------- -------------
     1024 Question      1.92 ms 1x
     1024 String.Create 3.32 ms 1.73x
     1024 StringBuilder 4.83 ms 2.51x

   WordCount: 10240

WordCount Test          Average RelativeSpeed
--------- ----          ------- -------------
    10240 String.Create 0.27 ms 1x
    10240 StringBuilder 0.39 ms 1.47x
    10240 Question      2.32 ms 8.71x

   WordCount: 51200

WordCount Test          Average  RelativeSpeed
--------- ----          -------  -------------
    51200 StringBuilder 0.45 ms  1x
    51200 String.Create 1.27 ms  2.79x
    51200 Question      13.05 ms 28.74x

   WordCount: 102400

WordCount Test          Average  RelativeSpeed
--------- ----          -------  -------------
   102400 StringBuilder 0.21 ms  1x
   102400 String.Create 1.99 ms  9.49x
   102400 Question      12.09 ms 57.57x

   WordCount: 512000

WordCount Test          Average  RelativeSpeed
--------- ----          -------  -------------
   512000 StringBuilder 0.25 ms  1x
   512000 String.Create 10.07 ms 40.59x
   512000 Question      58.96 ms 237.73x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment