Skip to content

Commit 160f973

Browse files
Merge pull request #5 from Open-NET-Libraries/StringBuilderHelper
StringBuilderHelper
2 parents 5c1c284 + 0fd1524 commit 160f973

19 files changed

Lines changed: 533 additions & 135 deletions

.editorconfig

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,11 @@ csharp_style_prefer_top_level_statements = true:silent
220220
csharp_style_prefer_local_over_anonymous_function = true:suggestion
221221
csharp_style_prefer_tuple_swap = true:suggestion
222222
csharp_style_prefer_utf8_string_literals = true:suggestion
223+
csharp_style_prefer_primary_constructors = true:suggestion
224+
dotnet_diagnostic.SYSLIB1045.severity = silent
225+
226+
# IDE0055: Fix formatting
227+
dotnet_diagnostic.IDE0055.severity = silent
223228

224229
[*.{cs,vb}]
225230
dotnet_style_operator_placement_when_wrapping = beginning_of_line
@@ -244,4 +249,7 @@ dotnet_style_prefer_inferred_tuple_names = true:suggestion
244249
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
245250
dotnet_style_prefer_compound_assignment = true:suggestion
246251
dotnet_style_prefer_simplified_interpolation = true:suggestion
247-
dotnet_style_namespace_match_folder = true:suggestion
252+
dotnet_style_namespace_match_folder = true:suggestion
253+
dotnet_diagnostic.CA1510.severity = silent
254+
dotnet_diagnostic.CA1512.severity = silent
255+
dotnet_diagnostic.CA1863.severity = none

Benchmarks/EnumParseTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ public bool IgnoreCase
5151
}
5252
}
5353

54-
static readonly string[] ValidValues = new string[] { nameof(Greek.Alpha), nameof(Greek.Epsilon), nameof(Greek.Phi), nameof(Greek.Beta), nameof(Greek.Gamma) };
55-
static readonly string[] InvalidValues = new string[] { "Apple", "Orange", "Pineapple", "Grapefruit", "Lemon" };
54+
static readonly string[] ValidValues = [nameof(Greek.Alpha), nameof(Greek.Epsilon), nameof(Greek.Phi), nameof(Greek.Beta), nameof(Greek.Gamma)];
55+
static readonly string[] InvalidValues = ["Apple", "Orange", "Pineapple", "Grapefruit", "Lemon"];
5656

5757
// To avoid branching overhead when benchmarking.
5858
abstract class Tests
@@ -67,7 +67,7 @@ abstract class Tests
6767

6868
public abstract Greek CompiledSwitchByLength();
6969

70-
static readonly IDictionary<string, Greek> LookupD
70+
static readonly Dictionary<string, Greek> LookupD
7171
= Enum
7272
.GetValues<Greek>()
7373
.ToDictionary(e => Enum.GetName(e)!, e => e, StringComparer.Ordinal);
@@ -260,7 +260,7 @@ public override Greek FastEnumParse()
260260
return e;
261261
}
262262

263-
static readonly IDictionary<string, Greek> LookupD
263+
static readonly Dictionary<string, Greek> LookupD
264264
= Enum
265265
.GetValues<Greek>()
266266
.ToDictionary(e => Enum.GetName(e)!, e => e, StringComparer.OrdinalIgnoreCase);
@@ -326,7 +326,7 @@ public override Greek FastEnumParse()
326326
return e;
327327
}
328328

329-
static readonly IDictionary<string, Greek> LookupD
329+
static readonly Dictionary<string, Greek> LookupD
330330
= Enum
331331
.GetValues<Greek>()
332332
.ToDictionary(e => Enum.GetName(e)!, e => e, StringComparer.OrdinalIgnoreCase);

Benchmarks/Greek.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
namespace Open.Text.Benchmarks;
22

33
[AttributeUsage(AttributeTargets.Field)]
4-
public class LetterAttribute : Attribute
4+
public class LetterAttribute(char upper, char lower) : Attribute
55
{
6-
public LetterAttribute(char upper, char lower)
7-
{
8-
Upper = upper;
9-
Lower = lower;
10-
}
11-
12-
public char Upper { get; }
13-
public char Lower { get; }
6+
public char Upper { get; } = upper;
7+
public char Lower { get; } = lower;
148

159
public bool EqualsLetter(char letter)
1610
=> letter == Upper || letter == Lower;

Benchmarks/Open.Text.Benchmarks.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net6.0</TargetFramework>
5+
<TargetFramework>net8.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>

Benchmarks/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
using BenchmarkDotNet.Running;
22
using Open.Text.Benchmarks;
33

4-
BenchmarkRunner.Run<EnumParseTests>();
4+
//BenchmarkRunner.Run<EnumParseTests>();
55
//enchmarkRunner.Run<EnumToStringTests>();
66
//BenchmarkRunner.Run<CharAssumptionTests>();
77
//BenchmarkRunner.Run<EnumAttributeTests>();
88
//BenchmarkRunner.Run<IsDefinedTests>();
9+
BenchmarkRunner.Run<StringConcatTests>();

Benchmarks/StringConcatTests.cs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using BenchmarkDotNet.Attributes;
2+
using Microsoft.Extensions.Primitives;
3+
using System.Text;
4+
using System.Diagnostics.CodeAnalysis;
5+
6+
namespace Open.Text.Benchmarks;
7+
8+
[MemoryDiagnoser]
9+
[SuppressMessage("Performance", "CA1822:Mark members as static")]
10+
public class StringConcatTests
11+
{
12+
public static readonly string Phrase
13+
= "Hello I'm from andromeda. Take me to your leader. There is nothing to fear.";
14+
15+
private static readonly ReadOnlyMemory<string> Words = Phrase.Split(' ');
16+
17+
private static readonly ReadOnlyMemory<StringSegment> Segments = Phrase.SplitAsSegments(' ').ToArray();
18+
19+
[Benchmark(Baseline = true)]
20+
public string StringOperator()
21+
{
22+
var s = "";
23+
{
24+
var len = Words.Length;
25+
var span = Words.Span;
26+
for (var i = 0; i < len; i++)
27+
s += span[i];
28+
}
29+
30+
{
31+
var len = Segments.Length;
32+
var span = Segments.Span;
33+
for (var i = 0; i < len; i++)
34+
s += span[i].ToString();
35+
}
36+
37+
return s;
38+
}
39+
40+
[Benchmark]
41+
public string StringBuilder()
42+
{
43+
var sb = new StringBuilder();
44+
{
45+
var len = Words.Length;
46+
var span = Words.Span;
47+
for (var i = 0; i < len; i++)
48+
sb.Append(span[i]);
49+
}
50+
51+
{
52+
var len = Segments.Length;
53+
var span = Segments.Span;
54+
for (var i = 0; i < len; i++)
55+
sb.AppendSegment(span[i]);
56+
}
57+
58+
return sb.ToString();
59+
}
60+
61+
[Benchmark]
62+
public string StringBuilderHelper()
63+
{
64+
StringBuilderHelper s = "";
65+
{
66+
var len = Words.Length;
67+
var span = Words.Span;
68+
for (var i = 0; i < len; i++)
69+
s += span[i];
70+
}
71+
72+
{
73+
var len = Segments.Length;
74+
var span = Segments.Span;
75+
for (var i = 0; i < len; i++)
76+
s += span[i];
77+
}
78+
79+
return s;
80+
}
81+
}

0 commit comments

Comments
 (0)