Skip to content

C#: Reduce Formatter String Allocations #779

@lordmilko

Description

@lordmilko

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions