Skip to content

Instantly share code, notes, and snippets.

@Bio2hazard
Created April 11, 2019 00:31
Show Gist options
  • Save Bio2hazard/1eca15d0f1394c474d7b1cd1a52861e4 to your computer and use it in GitHub Desktop.
Save Bio2hazard/1eca15d0f1394c474d7b1cd1a52861e4 to your computer and use it in GitHub Desktop.
An attempt to make allocation-free string fragment concatenation
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