Skip to content

Commit ed2d9e5

Browse files
committed
Enabled optimization
1 parent ee2e619 commit ed2d9e5

File tree

7 files changed

+99
-4
lines changed

7 files changed

+99
-4
lines changed

src/LinkDotNet.StringBuilder/TypedSpanList.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Buffers;
2+
using System.Runtime.CompilerServices;
23

34
namespace LinkDotNet.StringBuilder;
45

@@ -23,6 +24,7 @@ public TypedSpanList()
2324

2425
public ReadOnlySpan<T> AsSpan => buffer[..count];
2526

27+
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
2628
public void Add(T value)
2729
{
2830
if (count >= buffer.Length)

src/LinkDotNet.StringBuilder/ValueStringBuilder.Append.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public ref partial struct ValueStringBuilder
6969
/// Appends a string to the string builder.
7070
/// </summary>
7171
/// <param name="str">String, which will be added to this builder.</param>
72+
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
7273
public void Append(ReadOnlySpan<char> str)
7374
{
7475
var newSize = str.Length + bufferPosition;
@@ -84,6 +85,7 @@ public void Append(ReadOnlySpan<char> str)
8485
/// <summary>
8586
/// Adds the default new line separator.
8687
/// </summary>
88+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
8789
public void AppendLine()
8890
{
8991
Append(Environment.NewLine);
@@ -93,12 +95,14 @@ public void AppendLine()
9395
/// Does the same as <see cref="Append(char)"/> but adds a newline at the end.
9496
/// </summary>
9597
/// <param name="str">String, which will be added to this builder.</param>
98+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
9699
public void AppendLine(ReadOnlySpan<char> str)
97100
{
98101
Append(str);
99102
Append(Environment.NewLine);
100103
}
101104

105+
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
102106
private void AppendSpanFormattable<T>(T value)
103107
where T : ISpanFormattable
104108
{

src/LinkDotNet.StringBuilder/ValueStringBuilder.AppendJoin.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Runtime.CompilerServices;
2+
13
namespace LinkDotNet.StringBuilder;
24

35
public ref partial struct ValueStringBuilder
@@ -7,6 +9,7 @@ public ref partial struct ValueStringBuilder
79
/// </summary>
810
/// <param name="separator">String used as separator between the entries.</param>
911
/// <param name="values">Array of strings, which will be concatenated.</param>
12+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1013
public void AppendJoin(ReadOnlySpan<char> separator, IEnumerable<string?> values)
1114
=> AppendJoinInternalString(separator, values);
1215

@@ -15,6 +18,7 @@ public void AppendJoin(ReadOnlySpan<char> separator, IEnumerable<string?> values
1518
/// </summary>
1619
/// <param name="separator">Character used as separator between the entries.</param>
1720
/// <param name="values">Array of strings, which will be concatenated.</param>
21+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1822
public void AppendJoin(char separator, IEnumerable<string?> values)
1923
=> AppendJoinInternalChar(separator, values);
2024

@@ -24,6 +28,7 @@ public void AppendJoin(char separator, IEnumerable<string?> values)
2428
/// <param name="separator">String used as separator between the entries.</param>
2529
/// <param name="values">Array of strings, which will be concatenated.</param>
2630
/// <typeparam name="T">Type of the given array.</typeparam>
31+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2732
public void AppendJoin<T>(ReadOnlySpan<char> separator, IEnumerable<T> values)
2833
=> AppendJoinInternalString(separator, values);
2934

@@ -33,9 +38,11 @@ public void AppendJoin<T>(ReadOnlySpan<char> separator, IEnumerable<T> values)
3338
/// <param name="separator">Character used as separator between the entries.</param>
3439
/// <param name="values">Array of strings, which will be concatenated.</param>
3540
/// <typeparam name="T">Type of the given array.</typeparam>
41+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3642
public void AppendJoin<T>(char separator, IEnumerable<T> values)
3743
=> AppendJoinInternalChar(separator, values);
3844

45+
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
3946
private void AppendJoinInternalString<T2>(ReadOnlySpan<char> separator, IEnumerable<T2> values)
4047
{
4148
ArgumentNullException.ThrowIfNull(values);
@@ -64,6 +71,7 @@ private void AppendJoinInternalString<T2>(ReadOnlySpan<char> separator, IEnumera
6471
}
6572
}
6673

74+
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
6775
private void AppendJoinInternalChar<T2>(char separator, IEnumerable<T2> values)
6876
{
6977
ArgumentNullException.ThrowIfNull(values);
@@ -92,6 +100,7 @@ private void AppendJoinInternalChar<T2>(char separator, IEnumerable<T2> values)
92100
}
93101
}
94102

103+
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
95104
private void AppendInternal<T>(T value)
96105
{
97106
if (value is ISpanFormattable spanFormattable)

src/LinkDotNet.StringBuilder/ValueStringBuilder.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Buffers;
2+
using System.Runtime.CompilerServices;
23
using System.Runtime.InteropServices;
34

45
namespace LinkDotNet.StringBuilder;
@@ -81,6 +82,7 @@ public ref char GetPinnableReference()
8182
/// </summary>
8283
/// <param name="destination">The destination where the internal string is copied into.</param>
8384
/// <returns>True, if the copy was successful, otherwise false.</returns>
85+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
8486
public bool TryCopyTo(Span<char> destination) => buffer[..bufferPosition].TryCopyTo(destination);
8587

8688
/// <summary>
@@ -101,6 +103,7 @@ public void Clear()
101103
/// <remarks>
102104
/// If <paramref name="newCapacity"/> is smaller or equal to <see cref="Length"/> nothing will be done.
103105
/// </remarks>
106+
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
104107
public void EnsureCapacity(int newCapacity)
105108
{
106109
if (newCapacity < 0)
@@ -122,6 +125,7 @@ public void EnsureCapacity(int newCapacity)
122125
/// <remarks>
123126
/// This method will not affect the internal size of the string.
124127
/// </remarks>
128+
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
125129
public void Remove(int startIndex, int length)
126130
{
127131
if (length == 0)
@@ -154,6 +158,7 @@ public void Remove(int startIndex, int length)
154158
/// </summary>
155159
/// <param name="word">Word to look for in this string.</param>
156160
/// <returns>The index of the found <paramref name="word"/> in this string or -1 if not found.</returns>
161+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
157162
public int IndexOf(ReadOnlySpan<char> word) => IndexOf(word, 0);
158163

159164
/// <summary>
@@ -162,6 +167,7 @@ public void Remove(int startIndex, int length)
162167
/// <param name="word">Word to look for in this string.</param>
163168
/// <param name="startIndex">Index to begin with.</param>
164169
/// <returns>The index of the found <paramref name="word"/> in this string or -1 if not found.</returns>
170+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
165171
public int IndexOf(ReadOnlySpan<char> word, int startIndex)
166172
{
167173
if (startIndex < 0)
@@ -177,6 +183,7 @@ public int IndexOf(ReadOnlySpan<char> word, int startIndex)
177183
/// </summary>
178184
/// <param name="word">Word to look for in this string.</param>
179185
/// <returns>The index of the found <paramref name="word"/> in this string or -1 if not found.</returns>
186+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
180187
public int LastIndexOf(ReadOnlySpan<char> word) => LastIndexOf(word, 0);
181188

182189
/// <summary>
@@ -185,6 +192,7 @@ public int IndexOf(ReadOnlySpan<char> word, int startIndex)
185192
/// <param name="word">Word to look for in this string.</param>
186193
/// <param name="startIndex">Index to begin with.</param>
187194
/// <returns>The index of the found <paramref name="word"/> in this string or -1 if not found.</returns>
195+
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
188196
public int LastIndexOf(ReadOnlySpan<char> word, int startIndex)
189197
{
190198
if (startIndex < 0)
@@ -195,6 +203,7 @@ public int LastIndexOf(ReadOnlySpan<char> word, int startIndex)
195203
return NaiveSearch.FindLast(buffer[startIndex..bufferPosition], word);
196204
}
197205

206+
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
198207
private void Grow(int capacity = 0)
199208
{
200209
var currentSize = buffer.Length;

src/LinkDotNet.StringBuilder/ValueStringBuilderExtensions.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ public static System.Text.StringBuilder ToStringBuilder(ref this ValueStringBuil
2727
/// <exception cref="ArgumentNullException">Throws if <paramref name="builder"/> is null.</exception>
2828
public static ValueStringBuilder ToValueStringBuilder(this System.Text.StringBuilder? builder)
2929
{
30-
if (builder == null)
31-
{
32-
throw new ArgumentNullException(nameof(builder));
33-
}
30+
ArgumentNullException.ThrowIfNull(builder);
3431

3532
var valueStringBuilder = new ValueStringBuilder();
3633
foreach (var chunk in builder.GetChunks())

tests/LinkDotNet.StringBuilder.Benchmarks/AppendBenchmarks.cs renamed to tests/LinkDotNet.StringBuilder.Benchmarks/AppendBenchmark.cs

File renamed without changes.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using BenchmarkDotNet.Attributes;
2+
3+
namespace LinkDotNet.StringBuilder.Benchmarks;
4+
5+
[MemoryDiagnoser]
6+
public class ReplaceBenchmark
7+
{
8+
private const string Text =
9+
@"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae urna non leo dictum vestibulum eu quis massa. Aliquam pellentesque tempus porttitor. Nulla id enim id quam rhoncus condimentum. Nullam laoreet ornare pellentesque. Curabitur porta metus eget arcu aliquam tempor. Integer cursus enim ac efficitur finibus. Aenean sollicitudin ante leo, in facilisis tellus ultrices id. Morbi mi lacus, dictum non volutpat interdum, auctor vel dui.
10+
11+
Duis consectetur ac nunc ac auctor. Curabitur eget quam sit amet neque porttitor mattis vitae quis nulla. Etiam eleifend venenatis sapien, id ultrices neque iaculis eget. Curabitur cursus libero sodales, commodo purus hendrerit, elementum elit. Curabitur a nibh nec eros suscipit consectetur. Fusce nec leo dictum, sagittis erat in, sollicitudin ipsum. Proin mattis feugiat facilisis. Sed et maximus justo. Maecenas eget varius metus. Maecenas eleifend placerat placerat. Maecenas eget vestibulum quam. Sed id urna ultricies, pellentesque diam et, ultricies velit. Donec fermentum at nunc sed pellentesque.
12+
13+
Proin vulputate maximus nisl, quis dignissim velit rutrum pretium. Maecenas sed pharetra leo, eu semper ante. Sed erat dui, viverra quis commodo ut, viverra at tellus. Nullam pharetra, dolor eget varius consectetur, lacus nunc fermentum metus, at pretium enim est id justo. Mauris sed tincidunt felis. Curabitur eget vestibulum dolor, quis varius risus. Morbi erat metus, molestie non risus auctor, tempus vulputate purus. Ut ipsum tellus, posuere sed felis sed, facilisis efficitur justo. Aenean placerat molestie ex in ullamcorper. Mauris ex purus, vulputate ac nibh ut, bibendum mattis tortor. Nulla risus tellus, finibus sed fermentum id, hendrerit in urna. Integer sit amet efficitur sapien. Mauris posuere condimentum ipsum, quis ultricies ex tristique eget.
14+
15+
In eleifend tellus quis tincidunt commodo. Suspendisse potenti. Vestibulum dapibus congue imperdiet. Suspendisse et felis ac mi volutpat dignissim. Suspendisse feugiat tincidunt ipsum nec finibus. Nulla efficitur arcu pretium elit mattis ornare. Donec scelerisque dolor lacus, et mollis mauris vulputate nec. Suspendisse elit leo, efficitur eu justo sed, luctus imperdiet lorem. Donec pellentesque, massa semper posuere commodo, sapien magna rhoncus felis, et ultrices quam tellus ut purus. Curabitur eu fermentum nisl. Morbi malesuada pulvinar est, nec cursus massa aliquet a.
16+
17+
Cras suscipit blandit massa, non efficitur justo mollis sit amet. Fusce tellus mauris, maximus quis urna in, sollicitudin dictum est. Vivamus consectetur lorem quis turpis finibus aliquet. Nulla leo odio, lobortis viverra convallis sed, fringilla eu ligula. Nunc vitae metus ex. Suspendisse molestie orci ut nunc aliquet viverra. Donec id rutrum mi. Sed quis laoreet mi, vel mollis risus. Aliquam eget justo mattis, mollis urna ut, maximus sapien. Pellentesque sit amet fringilla quam, et fringilla dui.
18+
19+
Nam non blandit diam. Sed nec erat sollicitudin, fringilla leo ac, gravida ante. Sed molestie rutrum nulla, nec ultricies nulla laoreet ac. Vestibulum quis magna non turpis rhoncus viverra vel eget lacus. Aliquam quis est ultricies, hendrerit erat id, accumsan tortor. Phasellus iaculis vitae massa eu volutpat. Pellentesque lectus mi, pellentesque sit amet pretium aliquam, facilisis vitae mi.
20+
21+
Duis tempor lacus nulla, in consequat velit bibendum vel. Fusce a libero lacinia nunc commodo consectetur eget vel magna. Vestibulum ante elit, lacinia a laoreet et, malesuada non erat. Vivamus at ante non orci lacinia tempus id vel ante. Integer magna nulla, egestas vel ex ut, posuere porta orci. Donec vitae neque augue. Maecenas efficitur pharetra felis sit amet consequat. Donec placerat felis leo, eget dapibus libero vehicula eu. Pellentesque in fermentum orci.
22+
23+
Nullam turpis metus, efficitur id efficitur vel, fermentum at velit. Sed a eleifend nunc. Etiam tempor suscipit nibh, vel efficitur diam semper ac. Aliquam euismod fringilla justo consequat convallis. Proin nibh diam, egestas vitae tortor id, venenatis scelerisque augue. Sed hendrerit dolor elementum, tempor tortor quis, aliquet risus. Praesent feugiat quam id erat laoreet efficitur quis eget velit. Praesent a rutrum nulla. Mauris vel dignissim purus. Phasellus ornare purus nunc, at vehicula velit tempor eget. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Proin pretium pretium fermentum. Suspendisse at pharetra ipsum, in malesuada turpis. Ut id tincidunt justo. Ut dignissim velit ac sollicitudin porta.
24+
25+
Pellentesque feugiat congue libero, eget fringilla mi ornare quis. Proin ante sem, imperdiet quis venenatis et, pellentesque sed turpis. Mauris nibh lectus, elementum sed bibendum id, pretium et libero. Mauris gravida tempus lacus eu consectetur. Ut pulvinar elit purus, ut consequat arcu feugiat id. Suspendisse sed pretium leo, et aliquet metus. Aliquam erat volutpat. Pellentesque iaculis diam lacus, quis dictum mauris feugiat sed. Morbi vitae est a mi elementum facilisis a nec lectus. Integer id fermentum nulla. Donec tempor magna quis enim dignissim maximus. Aenean volutpat tincidunt faucibus.
26+
27+
Morbi maximus venenatis enim, in accumsan turpis aliquet nec. Ut tellus magna, interdum sed arcu sit amet, aliquam scelerisque risus. Phasellus a nunc mollis, gravida arcu vitae, tincidunt felis. Mauris sollicitudin, erat ac pretium ullamcorper, nibh odio vehicula sem, sit amet lobortis lacus orci sed nulla. Aenean sed ligula ac velit accumsan eleifend nec ac nunc. In diam ex, sodales sit amet convallis viverra, elementum sit amet arcu. Proin laoreet mauris vel eleifend dignissim. Curabitur non velit eget ex dictum porta in sed est. Nulla tempus magna vitae convallis cursus.
28+
29+
Fusce vestibulum neque arcu. In vitae felis felis. Quisque sed dictum eros. Fusce commodo nibh velit, sed accumsan tortor gravida vel. Mauris tincidunt fringilla arcu nec ultricies. Nam non efficitur velit. Quisque ac maximus risus. Etiam vulputate tortor ac felis fermentum, in malesuada elit porttitor.
30+
31+
Aliquam erat volutpat. Sed mollis eu nibh id feugiat. Cras a vestibulum arcu, eget aliquam orci. Etiam ut lacinia massa. Praesent non augue fringilla neque scelerisque ullamcorper. Vivamus varius rutrum leo, vitae ullamcorper diam aliquam et. Vivamus fringilla magna at quam efficitur, vitae convallis sapien rutrum. Duis ornare convallis nibh sit amet laoreet. Proin varius, elit quis mollis facilisis, dui tellus egestas est, auctor commodo eros enim in nisi. Etiam in massa nunc. Sed id ligula sit amet risus lacinia tincidunt. Sed pharetra arcu mi, at luctus metus viverra ut. Cras ex mi, porta quis vulputate a, lobortis nec tortor. In et ligula et diam tempor blandit in ut leo. Morbi accumsan convallis fringilla. Nam vel augue est.
32+
33+
Etiam eleifend sagittis vulputate. Aenean congue enim ac sem scelerisque, vel hendrerit leo facilisis. Vivamus aliquet faucibus congue. Aliquam sit amet sem porttitor.";
34+
35+
[Benchmark(Baseline = true)]
36+
public string DotNetStringBuilder()
37+
{
38+
var builder = new System.Text.StringBuilder();
39+
builder.Append(Text);
40+
builder.Replace("arcu", "some long word");
41+
builder.Replace("some long word", "arcu");
42+
builder.Replace("arcu", "some long word");
43+
builder.Replace("some long word", "arcu");
44+
builder.Replace("arcu", "some long word");
45+
builder.Replace("some long word", "arcu");
46+
builder.Replace("arcu", "some long word");
47+
builder.Replace("some long word", "arcu");
48+
builder.Replace("arcu", "some long word");
49+
builder.Replace("some long word", "arcu");
50+
builder.Replace("arcu", "some long word");
51+
builder.Replace("some long word", "arcu");
52+
return builder.ToString();
53+
}
54+
55+
[Benchmark]
56+
public string ValueStringBuilder()
57+
{
58+
var builder = new ValueStringBuilder();
59+
builder.Append(Text);
60+
builder.Replace("arcu", "some long word");
61+
builder.Replace("some long word", "arcu");
62+
builder.Replace("arcu", "some long word");
63+
builder.Replace("some long word", "arcu");
64+
builder.Replace("arcu", "some long word");
65+
builder.Replace("some long word", "arcu");
66+
builder.Replace("arcu", "some long word");
67+
builder.Replace("some long word", "arcu");
68+
builder.Replace("arcu", "some long word");
69+
builder.Replace("some long word", "arcu");
70+
builder.Replace("arcu", "some long word");
71+
builder.Replace("some long word", "arcu");
72+
return builder.ToString();
73+
}
74+
}

0 commit comments

Comments
 (0)