Created
April 11, 2019 00:31
-
-
Save Bio2hazard/1eca15d0f1394c474d7b1cd1a52861e4 to your computer and use it in GitHub Desktop.
An attempt to make allocation-free string fragment concatenation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public ref struct FastStringBuilder | |
{ | |
private int _pos; | |
private int _totalLength; | |
private readonly ReadOnlyMemory<char>[] _mems; | |
public FastStringBuilder(int maxPieces) | |
{ | |
_pos = 0; | |
_totalLength = 0; | |
_mems = new ReadOnlyMemory<char>[maxPieces]; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public void Append(ReadOnlyMemory<char> str) | |
{ | |
_mems[_pos] = str; | |
_pos++; | |
_totalLength += str.Length; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public void Append(string str) | |
{ | |
var mem = str.AsMemory(); | |
_mems[_pos] = mem; | |
_pos++; | |
_totalLength += mem.Length; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public void Append(string str, int start) | |
{ | |
var mem = str.AsMemory(start); ; | |
_mems[_pos] = mem; | |
_pos++; | |
_totalLength += mem.Length; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public void Append(string str, int start, int length) | |
{ | |
var mem = str.AsMemory(start, length); ; | |
_mems[_pos] = mem; | |
_pos++; | |
_totalLength += mem.Length; | |
} | |
public override string ToString() | |
{ | |
return string.Create( | |
_totalLength, | |
(Count: _pos, Pieces: _mems), | |
(destination, state) => | |
{ | |
int pos = 0; | |
for (int i = 0; i < state.Count; i++) | |
{ | |
var piece = state.Pieces[i].Span; | |
piece.CopyTo(destination.Slice(pos)); | |
pos += piece.Length; | |
} | |
} | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment