2018-03-27 16:42:52 +02:00
using System.Collections.Generic ;
using System.Linq ;
2022-06-21 08:09:38 +02:00
using BenchmarkDotNet.Attributes ;
2018-03-27 16:42:52 +02:00
using Umbraco.Tests.Benchmarks.Config ;
2022-06-21 08:09:38 +02:00
namespace Umbraco.Tests.Benchmarks ;
[QuickRunWithMemoryDiagnoserConfig]
public class StringReplaceManyBenchmarks
2018-03-27 16:42:52 +02:00
{
2022-06-21 08:09:38 +02:00
static StringReplaceManyBenchmarks ( )
2018-03-27 16:42:52 +02:00
{
2022-06-21 08:09:38 +02:00
// pick what you want to benchmark
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
// short
Text = "1,2.3:4&5#6" ;
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
// long
//Text = "Sed ut perspiciatis unde omnis iste natus &error sit voluptatem accusantium doloremque l:audantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et &quasi architecto beatae vitae ::dicta sunt explicabo. Nemo enim ipsam volupta:tem quia voluptas sit aspernatur aut o&dit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciun&t. Neque porro quisquam est, qui dolorem: ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut e:nim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi co&&nsequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse: quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?";
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
// short
Replacements = new Dictionary < string , string >
{
{ "," , "*" } ,
{ "." , "*" } ,
{ ":" , "*" } ,
{ "&" , "*" } ,
{ "#" , "*" }
} ;
// long
//Replacements = new Dictionary<string, string>();
//for (var i = 2; i < 100; i++)
// Replacements[Convert.ToChar(i).ToString()] = "*";
}
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
// this is what v7 originally did
[Benchmark(Description = "String.ReplaceMany w/chars - Aggregate", Baseline = true)]
public string ReplaceManyAggregate ( )
{
var result = Text ;
return ReplacedChars . Aggregate ( result , ( current , c ) = > current . Replace ( c , ReplacementChar ) ) ;
}
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
[Benchmark(Description = "String.ReplaceMany w/chars - For Loop")]
public string ReplaceManyForLoop ( )
{
var result = Text ;
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
// ReSharper disable once LoopCanBeConvertedToQuery
// ReSharper disable once ForCanBeConvertedToForeach
for ( var i = 0 ; i < ReplacedChars . Length ; i + + )
{
result = result . Replace ( ReplacedChars [ i ] , ReplacementChar ) ;
}
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
return result ;
}
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
// this is what v7 originally did
[Benchmark(Description = "String.ReplaceMany w/dictionary - Aggregate")]
public string ReplaceManyDictionaryAggregate ( ) = >
Replacements . Aggregate ( Text , ( current , kvp ) = > current . Replace ( kvp . Key , kvp . Value ) ) ;
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
[Benchmark(Description = "String.ReplaceMany w/dictionary - For Each")]
public string ReplaceManyDictionaryForEach ( )
{
var result = Text ;
// ReSharper disable once LoopCanBeConvertedToQuery
foreach ( var item in Replacements )
{
result = result . Replace ( item . Key , item . Value ) ;
}
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
return result ;
}
/ *
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
short text , short replacement :
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
Method | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | - - - - - - - - - : | - - - - - - - - - - : | - - - - - - - - - - : | - - - - - - - : | - - - - - - - - - : | - - - - - - - : | - - - - - - - - - - : |
' String . ReplaceMany w / chars - Aggregate ' | 236.0 ns | 40.92 ns | 2.312 ns | 1.00 | 0.00 | 0.0461 | 200 B |
' String . ReplaceMany w / chars - For Loop ' | 166.7 ns | 70.51 ns | 3.984 ns | 0.71 | 0.01 | 0.0420 | 180 B |
' String . ReplaceMany w / dictionary - Aggregate ' | 606.5 ns | 342.94 ns | 19.377 ns | 2.57 | 0.07 | 0.0473 | 212 B |
' String . ReplaceMany w / dictionary - For Each ' | 571.8 ns | 232.33 ns | 13.127 ns | 2.42 | 0.05 | 0.0458 | 212 B |
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
long text , short replacement :
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
Method | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | - - - - - - - - - - : | - - - - - - - - - - : | - - - - - - - - - - : | - - - - - - - : | - - - - - - - - - : | - - - - - - - : | - - - - - - - - - - : |
' String . ReplaceMany w / chars - Aggregate ' | 5.771 us | 9.963 us | 0.5630 us | 1.00 | 0.00 | 1.6798 | 6.94 KB |
' String . ReplaceMany w / chars - For Loop ' | 4.962 us | 2.121 us | 0.1199 us | 0.87 | 0.08 | 1.6840 | 6.92 KB |
' String . ReplaceMany w / dictionary - Aggregate ' | 14.514 us | 8.189 us | 0.4627 us | 2.53 | 0.22 | 1.6447 | 6.96 KB |
' String . ReplaceMany w / dictionary - For Each ' | 15.445 us | 24.745 us | 1.3981 us | 2.69 | 0.30 | 1.5696 | 6.96 KB |
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
short text , long replacements dictionary :
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
Method | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | - - - - - - - - - - - : | - - - - - - - - - - - : | - - - - - - - - - - : | - - - - - - - : | - - - - - - - - - : | - - - - - - - : | - - - - - - - - - - : |
' String . ReplaceMany w / chars - Aggregate ' | 257.0 ns | 200.0 ns | 11.30 ns | 1.00 | 0.00 | 0.0452 | 200 B |
' String . ReplaceMany w / chars - For Loop ' | 182.4 ns | 221.0 ns | 12.49 ns | 0.71 | 0.05 | 0.0425 | 180 B |
' String . ReplaceMany w / dictionary - Aggregate ' | 7 , 273.8 ns | 2 , 747.1 ns | 155.22 ns | 28.34 | 1.12 | 0.0714 | 464 B |
' String . ReplaceMany w / dictionary - For Each ' | 6 , 981.0 ns | 5 , 500.7 ns | 310.80 ns | 27.20 | 1.38 | 0.0775 | 464 B |
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
long text , long replacements dictionary :
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
Method | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | - - - - - - - - - - - : | - - - - - - - - - - - : | - - - - - - - - - - - : | - - - - - - - : | - - - - - - - - - : | - - - - - - - : | - - - - - - - - - - : |
' String . ReplaceMany w / chars - Aggregate ' | 4.868 us | 3.420 us | 0.1932 us | 1.00 | 0.00 | 1.6816 | 6.94 KB |
' String . ReplaceMany w / chars - For Loop ' | 4.958 us | 2.633 us | 0.1487 us | 1.02 | 0.04 | 1.6791 | 6.92 KB |
' String . ReplaceMany w / dictionary - Aggregate ' | 181.309 us | 210.177 us | 11.8754 us | 37.29 | 2.32 | 5.3571 | 24.28 KB |
' String . ReplaceMany w / dictionary - For Each ' | 174.567 us | 113.733 us | 6.4262 us | 35.90 | 1.57 | 5.8594 | 24.28 KB |
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
* /
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
// don't use constants
// ReSharper disable ConvertToConstant.Local
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
// input text for ReplaceMany
private static readonly string Text ;
2018-03-27 16:42:52 +02:00
2022-06-21 08:09:38 +02:00
// replaced chars for ReplaceMany with chars
private static readonly char [ ] ReplacedChars = { ',' , '.' , ':' , '&' , '#' } ;
// replacement char for ReplaceMany with chars
private static readonly char ReplacementChar = '*' ;
// replacements for ReplaceMany with dictionary
private static readonly IDictionary < string , string > Replacements ;
// ReSharper restore ConvertToConstant.Local
}