Repository navigation
Releases: linkdotnet/StringBuilder
Releases · linkdotnet/StringBuilder
Release list
v3.7.4
Changed
Replacewith a value of a different length searches the text once instead of twice.AppendFormatsearches for placeholders vectorized and reads single-digit indices like{0}withoutint.TryParse.Append(bool)writes without pinning or bounds checks,Append(Rune)andInsert(int, Rune)skip the stack buffer for BMP runes, andstringvalues inAppendJoin,AppendFormatandConcatskip theISpanFormattablecheck.
v3.7.3
Fixed
AppendFormatwith an unclosed{appended the whole format string a second time ("Hello {0} and {"gave"Hello 1Hello {0} and {"). Now only the not yet written rest is appended.TrimPrefixandTrimSuffixwith a culture-sensitiveStringComparisonremovedvalue.Lengthcharacters instead of the actual match length, so ignorable or composed characters left the wrong content behind or madeTrimSuffixthrow.Insert(int, ReadOnlySpan<char>)produced wrong content when the inserted span points into the builder itself (e.g.builder.Insert(0, builder.AsSpan(1))).- Interpolated strings passed no format to types that implement
IFormattablebut notISpanFormattable, so$"{value:X}"calledToString()instead ofToString("X", null). Applies toValueStringBuilderandFixedSizeValueStringBuilder. AppendSpanwith a negative length decreasedLengthbefore throwing. It now throws anArgumentOutOfRangeExceptionup front and leaves the builder untouched.Insert<T>forISpanFormattablevalues grows likeAppend<T>when the formatted value exceeds the default buffer size of 36 characters, instead of throwing anInvalidOperationException. A custombufferSizestill throws when it is too small.Insert<T>stack-allocated the caller-providedbufferSizeunbounded, so a large value crashed the process with a stack overflow. Sizes above 256 characters are now rented from theArrayPool.
v3.7.2
Fixed
AsSpan(int startIndex, int length)andToString(int startIndex, int length)throw anArgumentOutOfRangeExceptionwhen the requested range ends afterLength, instead of returning characters from the unused part of the buffer.- The indexer throws an
IndexOutOfRangeExceptionfor an index at or afterLength, instead of giving access to the unused part of the buffer. Append/AppendLinewith an interpolated string could return the rented array to theArrayPooltwice when an interpolation hole threw after the buffer grew. Reported by @dhhoang in #324
v3.7.1
Added
ValueStringBuilderinterpolated strings support alignment holes such as$"{value,10}"and$"{value,-10:F2}", likeFixedSizeValueStringBuilder.ValueStringBuilder.Append(char value, int repeatCount).
Changed
- Any
ISpanFormattablevalue type (not only the built-in well-known ones) is formatted without boxing in interpolated strings,AppendJoin,Concat,AppendFormatandReplaceGeneric. Append<T>forISpanFormattablevalues first formats into the remaining buffer and only grows when the value does not fit, instead of reserving 36 characters up front.AppendJoinwith anIEnumerable<T>that is an array orList<T>no longer allocates an enumerator.- Growing the buffer is moved out of the inlined
Appendfast paths, which makes them smaller. Append(char)does a single bounds check per character (about 40% faster in a tight loop).AppendJoinand friends dispatch value types through a small inlinable helper instead of a 20-entry type table, which the JIT could not inline in deep call chains (AppendJoinover ints about 40% faster).
v3.7.0
Added
FixedSizeValueStringBuilder: a non-growingref structstring builder backed by a caller-supplied buffer that never allocates on the heap. Appends are atomic and the first one that does not fit latchesOverflowed, whichClearOverflowresets.FixedSizeValueStringBuilder.MoveToValueStringBuilder: hands the buffer and its content over to aValueStringBuilderwhich can grow beyond the fixed capacity. The move copies nothing and rents nothing, and consumes the source so both builders can never write into the same memory.
v3.6.1
Changed
- Removed some wrong
[MethodImpl(MethodImplOptions.AggressiveInlining)]attributes that might made it worse.
v3.6.0
Changed
- Performance upgrades when growing
v3.5.0
Added
- Avoid boxing common value types (
int,long,double,decimal,DateTime,DateTimeOffset,TimeSpan,Guid, and 12 more) when passed toAppendJoin,Concat,AppendFormat,ReplaceGeneric, or interpolated strings. - Vectorized
Trim,TrimStart, andTrimEnd(both the whitespace and character overloads) viaSearchValues<char>, making them significantly faster on large buffers.
### Changed
- Small improvement to get the next "Grow" iteration
Fixed
- Sizing bugs in
AppendandTrim
v3.4.2
v3.4.1
Fixed
- Use correct culture (
CurrentCulture) when noFormatProvideris provided inAppendandInsertmethods.