1+ [ MemoryDiagnoser ]
2+ [ SimpleJob ( warmupCount : 3 , iterationCount : 5 ) ]
3+ public class OverwriteBenchmarks
4+ {
5+ StringBuilder smallBuilder = null ! ;
6+ StringBuilder mediumBuilder = null ! ;
7+ StringBuilder largeBuilder = null ! ;
8+ StringBuilder multiChunkBuilder = null ! ;
9+
10+ [ GlobalSetup ]
11+ public void Setup ( )
12+ {
13+ smallBuilder = new StringBuilder ( "Hello World! This is a small test string." ) ;
14+
15+ mediumBuilder = new StringBuilder ( ) ;
16+ for ( var i = 0 ; i < 100 ; i ++ )
17+ {
18+ mediumBuilder . Append ( "This is sentence number " ) ;
19+ mediumBuilder . Append ( i ) ;
20+ mediumBuilder . Append ( ". " ) ;
21+ }
22+
23+ largeBuilder = new StringBuilder ( ) ;
24+ for ( var i = 0 ; i < 10000 ; i ++ )
25+ {
26+ largeBuilder . Append ( "Content " ) ;
27+ }
28+
29+ // Force multiple chunks
30+ multiChunkBuilder = new StringBuilder ( ) ;
31+ for ( var i = 0 ; i < 50 ; i ++ )
32+ {
33+ multiChunkBuilder . Append ( "Chunk " ) ;
34+ multiChunkBuilder . Append ( i ) ;
35+ multiChunkBuilder . Append ( " data. " ) ;
36+ }
37+ }
38+
39+ // Same length replacements - most common case
40+ [ Benchmark ]
41+ public void SameLength_Small_SingleChar ( )
42+ {
43+ var builder = new StringBuilder ( smallBuilder . ToString ( ) ) ;
44+ builder . Overwrite ( "X" , 0 , 1 ) ;
45+ }
46+
47+ [ Benchmark ]
48+ public void SameLength_Small_FiveChars ( )
49+ {
50+ var builder = new StringBuilder ( smallBuilder . ToString ( ) ) ;
51+ builder . Overwrite ( "XXXXX" , 6 , 5 ) ;
52+ }
53+
54+ [ Benchmark ]
55+ public void SameLength_Small_TenChars ( )
56+ {
57+ var builder = new StringBuilder ( smallBuilder . ToString ( ) ) ;
58+ builder . Overwrite ( "XXXXXXXXXX" , 10 , 10 ) ;
59+ }
60+
61+ [ Benchmark ]
62+ public void SameLength_Medium_TenChars ( )
63+ {
64+ var builder = new StringBuilder ( mediumBuilder . ToString ( ) ) ;
65+ builder . Overwrite ( "REPLACEMENT" , 500 , 11 ) ;
66+ }
67+
68+ [ Benchmark ]
69+ public void SameLength_Large_TenChars ( )
70+ {
71+ var builder = new StringBuilder ( largeBuilder . ToString ( ) ) ;
72+ builder . Overwrite ( "REPLACEMENT" , 5000 , 11 ) ;
73+ }
74+
75+ [ Benchmark ]
76+ public void SameLength_MultiChunk_SpanningChunks ( )
77+ {
78+ var builder = new StringBuilder ( multiChunkBuilder . ToString ( ) ) ;
79+ builder . Overwrite ( "REPLACED" , 50 , 8 ) ;
80+ }
81+
82+ // Shorter replacements
83+ [ Benchmark ]
84+ public void Shorter_Small_ReplaceWithEmpty ( )
85+ {
86+ var builder = new StringBuilder ( smallBuilder . ToString ( ) ) ;
87+ builder . Overwrite ( "" , 6 , 5 ) ;
88+ }
89+
90+ [ Benchmark ]
91+ public void Shorter_Small_ReplaceWithOne ( )
92+ {
93+ var builder = new StringBuilder ( smallBuilder . ToString ( ) ) ;
94+ builder . Overwrite ( "X" , 6 , 5 ) ;
95+ }
96+
97+ [ Benchmark ]
98+ public void Shorter_Medium ( )
99+ {
100+ var builder = new StringBuilder ( mediumBuilder . ToString ( ) ) ;
101+ builder . Overwrite ( "SHORT" , 500 , 20 ) ;
102+ }
103+
104+ [ Benchmark ]
105+ public void Shorter_Large ( )
106+ {
107+ var builder = new StringBuilder ( largeBuilder . ToString ( ) ) ;
108+ builder . Overwrite ( "X" , 5000 , 100 ) ;
109+ }
110+
111+ // Longer replacements
112+ [ Benchmark ]
113+ public void Longer_Small ( )
114+ {
115+ var builder = new StringBuilder ( smallBuilder . ToString ( ) ) ;
116+ builder . Overwrite ( "MUCH LONGER REPLACEMENT" , 6 , 5 ) ;
117+ }
118+
119+ [ Benchmark ]
120+ public void Longer_Medium ( )
121+ {
122+ var builder = new StringBuilder ( mediumBuilder . ToString ( ) ) ;
123+ builder . Overwrite ( "THIS IS A MUCH LONGER REPLACEMENT STRING" , 500 , 10 ) ;
124+ }
125+
126+ [ Benchmark ]
127+ public void Longer_Large ( )
128+ {
129+ var builder = new StringBuilder ( largeBuilder . ToString ( ) ) ;
130+ builder . Overwrite ( "VERY LONG REPLACEMENT TEXT HERE" , 5000 , 10 ) ;
131+ }
132+
133+ // Position-based tests
134+ [ Benchmark ]
135+ public void SameLength_AtStart ( )
136+ {
137+ var builder = new StringBuilder ( mediumBuilder . ToString ( ) ) ;
138+ builder . Overwrite ( "REPLACED" , 0 , 8 ) ;
139+ }
140+
141+ [ Benchmark ]
142+ public void SameLength_AtEnd ( )
143+ {
144+ var builder = new StringBuilder ( mediumBuilder . ToString ( ) ) ;
145+ var length = builder . Length ;
146+ builder . Overwrite ( "REPLACED" , length - 8 , 8 ) ;
147+ }
148+
149+ [ Benchmark ]
150+ public void SameLength_InMiddle ( )
151+ {
152+ var builder = new StringBuilder ( mediumBuilder . ToString ( ) ) ;
153+ var length = builder . Length ;
154+ builder . Overwrite ( "REPLACED" , length / 2 , 8 ) ;
155+ }
156+
157+ // Multiple operations
158+ [ Benchmark ]
159+ public void MultipleOverwrites_SameLength ( )
160+ {
161+ var builder = new StringBuilder ( mediumBuilder . ToString ( ) ) ;
162+ for ( var i = 0 ; i < 10 ; i ++ )
163+ {
164+ builder . Overwrite ( "REPLACE" , i * 100 , 7 ) ;
165+ }
166+ }
167+
168+ [ Benchmark ]
169+ public void MultipleOverwrites_DifferentLengths ( )
170+ {
171+ var builder = new StringBuilder ( mediumBuilder . ToString ( ) ) ;
172+ builder . Overwrite ( "SHORT" , 100 , 10 ) ;
173+ builder . Overwrite ( "MUCH LONGER" , 200 , 5 ) ;
174+ builder . Overwrite ( "SAME" , 300 , 4 ) ;
175+ }
176+
177+ // Edge cases
178+ [ Benchmark ]
179+ public void EdgeCase_VeryLongReplacement ( )
180+ {
181+ var builder = new StringBuilder ( mediumBuilder . ToString ( ) ) ;
182+ var longString = new string ( 'X' , 500 ) ;
183+ builder . Overwrite ( longString , 100 , 50 ) ;
184+ }
185+
186+ [ Benchmark ]
187+ public void EdgeCase_SingleCharReplace ( )
188+ {
189+ var builder = new StringBuilder ( largeBuilder . ToString ( ) ) ;
190+ builder . Overwrite ( "Y" , 5000 , 1 ) ;
191+ }
192+
193+ [ Benchmark ]
194+ public void EdgeCase_NearChunkBoundary ( )
195+ {
196+ var builder = new StringBuilder ( multiChunkBuilder . ToString ( ) ) ;
197+ // Try to hit near chunk boundaries
198+ builder . Overwrite ( "BOUNDARY" , 15 , 8 ) ;
199+ }
200+ }
0 commit comments