Add ReadOnlySpan<char> overloads to the DecimalNotationFormatter
In order to easily support the ISpanFormattable interface, see about adding an overload to the DecimalNotationFormatter that works with a ReadOnlySpan<char>
This should further reduce the allocations required for formatting strings that contain a Fraction as part of the format.
This is up for grabs (I'll probably look into it at some point):
Hey,
I have nothing against the introduction of Span/ReadOnlySpan method overloads. Several people from my work environment pointed out to me, that the use of #if/#else preprocessor directives makes the code confusing.
I may outsource the affected functions to different files in future. Example file layout:
- Fraction.FromString.cs (general, available in both, netstandard and netcore)
- Fraction.FromString-netstandard.cs (.NET Standard implementation)
- Fraction.FromString-netcore.cs (.NET Core implementation)
I was able to implement this in my other project, and the performance improvements (over using the StringBuilder approach) is quite significant.
The implication is that now there are two completely separate, but similar (at least in spirit) implementations of the DecimalNotationFormatter - and you know how much code that is...
I was able to re-use most of the existing tests, since Format(fraction, "G") for NET is calling into the TryFormat overload, but there are now also a bunch of new tests where we're trying to format into a destination Span<char> that isn't large enough. It took a lot of work to get the coverage back to 100%..
Just consider one of the new functions:
static bool TryAppendLeadingNegativePattern(Span<char> destination, out int charsWritten, string negativeSignSymbol, int pattern)
{
charsWritten = 0;
switch (pattern)
{
case 0: // (n) : leading is '('
if (destination.IsEmpty)
{
return false;
}
destination[0] = '(';
charsWritten = 1;
return true;
case 1: // -n : leading is negativeSignSymbol
if (!negativeSignSymbol.TryCopyTo(destination))
{
return false;
}
charsWritten = negativeSignSymbol.Length;
return true;
case 2: // - n : leading is negativeSignSymbol + ' '
if (!negativeSignSymbol.TryCopyTo(destination))
{
return false;
}
charsWritten = negativeSignSymbol.Length;
if (charsWritten == destination.Length)
{
return false;
}
destination[charsWritten] = ' ';
charsWritten++;
return true;
default: //"n-" and "n -" : no leading addition
return true;
}
}
And imagine what this looks like for the negative currency or percent formats..
I'd understand if you don't want to deal with that much optimization...