In the C# Iced implementation, many methods on the Formatter class (such as Formatter.FormatUInt64) directly return a string, causing an allocation. The typical implementation of classes that derive from Formatter is to forward to the internal NumberFormatter type, which holds an internal StringBuilder and allocates a new string for each number that is formatted. All of these strings are required because the FormatterOutput requires strings be passed to its various Write methods.
I am seeing a lot of allocations from formatting instructions in my application. I am trying to explore how I can reduce these allocations. I think ideally, the behavior of Iced would be
- The
Formatter type has TryFormat* overloads that allows the caller to potentially pass in a Span<char> to write into
- For the scenarios where Iced's formatters are using these formatters internally, they could use a
char[] instead (potentially stackalloc'd, or otherwise cached on the formatter and grown as needed?). There's also some FormatDispl* methods on NumberFormatter that have the same issue
- The existing formatter methods that return strings could potentially forward to the new span based methods
- Add additional overloads to
FormatterOutput that emit ReadOnlySpan<char> rather than string. The default implementation of these new overloads might be to forward to the existing string based overloads? Not sure I'm really a fan of having two sets of methods here, but could be a viable way of achieving things without causing breaking changes
I'm not sure to what extent the other languages Iced supports may have equivalent mechanisms to Span that should also be taken into account to achieve uniformity between the various Iced implementations, which would complicate things further.
In the C# Iced implementation, many methods on the
Formatterclass (such asFormatter.FormatUInt64) directly return a string, causing an allocation. The typical implementation of classes that derive fromFormatteris to forward to the internalNumberFormattertype, which holds an internalStringBuilderand allocates a new string for each number that is formatted. All of these strings are required because theFormatterOutputrequires strings be passed to its variousWritemethods.I am seeing a lot of allocations from formatting instructions in my application. I am trying to explore how I can reduce these allocations. I think ideally, the behavior of Iced would be
Formattertype hasTryFormat*overloads that allows the caller to potentially pass in aSpan<char>to write intochar[]instead (potentially stackalloc'd, or otherwise cached on the formatter and grown as needed?). There's also someFormatDispl*methods onNumberFormatterthat have the same issueFormatterOutputthat emitReadOnlySpan<char>rather thanstring. The default implementation of these new overloads might be to forward to the existing string based overloads? Not sure I'm really a fan of having two sets of methods here, but could be a viable way of achieving things without causing breaking changesI'm not sure to what extent the other languages Iced supports may have equivalent mechanisms to
Spanthat should also be taken into account to achieve uniformity between the various Iced implementations, which would complicate things further.