Skip to content

Commit 89f9d84

Browse files
feat:
+ clear method and refactor for reuse memory and existing chain
1 parent f217de7 commit 89f9d84

File tree

5 files changed

+129
-9
lines changed

5 files changed

+129
-9
lines changed

Src/Benchmark/CompareStringBuilders.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ namespace Benchmark
55
{
66
[MemoryDiagnoser]
77
[SimpleJob(RuntimeMoniker.Net70)]
8-
[SimpleJob(RuntimeMoniker.Net481)]
98
[HideColumns("Error", "StdDev", "Median", "RatioSD")]
109
public partial class CompareStringBuilders
1110
{
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using BenchmarkDotNet.Attributes;
2+
using BenchmarkDotNet.Jobs;
3+
4+
namespace Benchmark
5+
{
6+
[MemoryDiagnoser]
7+
[SimpleJob(RuntimeMoniker.Net70)]
8+
[HideColumns("Error", "StdDev", "Median", "RatioSD")]
9+
public partial class CompareStringBuildersClear
10+
{
11+
[Params(5, 7, 10, 50, 100, 1000, 2500, 5_000, 10_000, 100_000, 500_000, 1_071_741)]
12+
public int StrLength;
13+
14+
private string _str;
15+
16+
[IterationSetup]
17+
public void Setup()
18+
{
19+
_str = new string('S', StrLength);
20+
}
21+
22+
[Benchmark(Baseline = true, Description = "StringBuilder")]
23+
public void StringBuilder()
24+
{
25+
var sb = new System.Text.StringBuilder();
26+
for (int i = 0; i < 1000; i++)
27+
{
28+
sb.AppendLine(_str);
29+
}
30+
31+
sb.Clear();
32+
for (int i = 0; i < 1000; i++)
33+
{
34+
sb.AppendLine(_str);
35+
}
36+
37+
var result = sb.ToString();
38+
}
39+
40+
[Benchmark(Description = "StringBuilderArray")]
41+
public void StringBuilderArray()
42+
{
43+
var sb = new StringBuilderArray.StringBuilderArray();
44+
for (int i = 0; i < 1000; i++)
45+
{
46+
sb.AppendLine(_str);
47+
}
48+
49+
sb.Clear();
50+
for (int i = 0; i < 1000; i++)
51+
{
52+
sb.AppendLine(_str);
53+
}
54+
55+
var result = sb.ToString();
56+
}
57+
}
58+
}

Src/Benchmark/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ internal class Program
77
static void Main(string[] args)
88
{
99
BenchmarkRunner.Run<CompareStringBuilders>();
10+
BenchmarkRunner.Run<CompareStringBuildersClear>();
1011
}
1112
}
1213
}

Src/StringBuilderArray/StringBuilderArray.cs

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace StringBuilderArray
66
public class StringBuilderArray
77
{
88
private StringBuilderArray _previous;
9+
private StringBuilderArray _next;
910
private string[] _buffer;
1011
private int _size;
1112
private int _length;
@@ -36,6 +37,10 @@ private StringBuilderArray(StringBuilderArray stringBuilderArray)
3637
_size = stringBuilderArray._size;
3738
_length = stringBuilderArray._length;
3839
_previous = stringBuilderArray._previous;
40+
if(_previous != null)
41+
{
42+
_previous._next = this;
43+
}
3944
}
4045

4146
public int Length
@@ -60,14 +65,40 @@ public StringBuilderArray Append(string str)
6065
{
6166
if (_size == _buffer.Length)
6267
{
63-
Grow();
68+
MakeThisPrevious();
6469
}
65-
70+
6671
_buffer[_size++] = str;
6772
_length += str.Length;
6873
return this;
6974
}
7075

76+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
77+
private void MakeThisPrevious()
78+
{
79+
if(_next != null)
80+
{
81+
_previous = new StringBuilderArray(this);
82+
_next._previous = null;
83+
84+
_buffer = _next._buffer;
85+
_next._buffer = null;
86+
87+
var tempNext = _next;
88+
_next = _next._next;
89+
tempNext._next = null;
90+
}
91+
else
92+
{
93+
_previous = new StringBuilderArray(this);
94+
int newBufferLength = Math.Max(10, Math.Min(_buffer.Length * 2, MaxChunkSize));
95+
_buffer = new string[newBufferLength];
96+
}
97+
98+
_size = 0;
99+
_length = 0;
100+
}
101+
71102
public StringBuilderArray AppendLine(string str)
72103
{
73104
Append(str);
@@ -96,15 +127,46 @@ public StringBuilderArray AppendLine(string[] strings)
96127
return this;
97128
}
98129

99-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
100-
private void Grow()
130+
public StringBuilderArray Clear()
101131
{
102-
_previous = new StringBuilderArray(this);
132+
StringBuilderArray head = null;
133+
var current = this;
134+
do
135+
{
136+
head = current;
137+
current._length = 0;
138+
current._size = 0;
139+
#if NET6_0_OR_GREATER
140+
Array.Clear(current._buffer);
141+
#else
142+
Array.Clear(current._buffer, 0, current._buffer.Length);
143+
#endif
144+
current = current._previous;
145+
} while (current != null);
103146

104-
int newBufferLength = Math.Max(10, Math.Min(_buffer.Length * 2, MaxChunkSize));
105-
_buffer = new string[newBufferLength];
147+
current = this._next;
148+
while (current != null)
149+
{
150+
current._length = 0;
151+
current._size = 0;
152+
#if NET6_0_OR_GREATER
153+
Array.Clear(current._buffer);
154+
#else
155+
Array.Clear(current._buffer, 0, current._buffer.Length);
156+
#endif
157+
current = current._next;
158+
}
159+
160+
//make this head
161+
_previous = null;
162+
_next = head._next;
163+
_buffer = head._buffer;
106164
_size = 0;
107165
_length = 0;
166+
head._next = null;
167+
head._previous = null;
168+
169+
return this;
108170
}
109171

110172
public override string ToString()

Src/StringBuilderArray/StringBuilderArray.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</PropertyGroup>
66
<PropertyGroup>
77
<PackageId>StringBuilderArray</PackageId>
8-
<PackageVersion>1.0.0.1</PackageVersion>
8+
<PackageVersion>1.1.0.0</PackageVersion>
99
<Authors>Brevnov Vyacheslav Sergeevich</Authors>
1010
<RepositoryUrl>https://github.com/SoftStoneDevelop/StringBuilderArray</RepositoryUrl>
1111
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>

0 commit comments

Comments
 (0)