New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement ISpanFormattable to improve string interpolation performance #244
Comments
I thought of it. The big downside I see, is that it will result in the formatting code being duplicated. I'm not sure yet if that is worth the small gain in performance. Do you have experience with it yourself? |
I did some comparisons and saw a 50% performance improvement. But it is a lot of work to write the readonly record struct Point {
public readonly int X, Y;
public Point(int x, int y) => (X, Y) = (x, y);
public override string ToString() => $"({X},{Y})";
} readonly record struct Point : ISpanFormattable {
public readonly int X, Y;
public Point(int x, int y) => (X, Y) = (x, y);
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider) {
destination[0] = '(';
charsWritten = 1;
destination = destination.Slice(1);
if (!X.TryFormat(destination, out int tmpCharsWritten, format, provider)) {
return false;
}
charsWritten += tmpCharsWritten;
destination = destination.Slice(tmpCharsWritten);
if (destination.Length < 3) { // not enough room to write the , Y and )
return false;
}
destination[0] = ',';
destination = destination.Slice(1);
charsWritten++;
if (!Y.TryFormat(destination, out tmpCharsWritten, format, provider)) {
return false;
}
if (destination.Length < tmpCharsWritten + 1) { // not enough room to write the )
return false;
}
destination[tmpCharsWritten] = ')';
charsWritten += tmpCharsWritten + 1;
return true;
}
public override string ToString() => $"({X},{Y})";
public string ToString(string? format, IFormatProvider? formatProvider) => $"({X.ToString(format, formatProvider)},{Y.ToString(format, formatProvider)})";
} You can use a simple approach using the var p = new Point(3, 4);
Console.WriteLine($"Point {p}");
readonly record struct Point : ISpanFormattable {
public readonly int X, Y;
public Point(int x, int y) => (X, Y) = (x, y);
public bool TryFormat(Span<char> destination, out int charsWritten,
ReadOnlySpan<char> format, IFormatProvider? provider) =>
destination.TryWrite($"({X},{Y})", out charsWritten);
public override string ToString() => $"({X},{Y})";
public string ToString(string? format, IFormatProvider? formatProvider) =>
$"({X.ToString(format, formatProvider)},{Y.ToString(format, formatProvider)})";
} |
We need 26 of them, and most of them are way more complex than this Point implementation. :( |
Maybe you can put it on the backlog |
Are you planning to implement the
ISpanFormattable
interface on the structs? This can improve the performance of string interpolation. It only works in .NET 6 so it requires some conditional compilation.The text was updated successfully, but these errors were encountered: