Improve performance of managed formatting code
- Optimize NumberBuffer passing by reference instead of value. It's a large struct of ~50 bytes; copying it around has non-trivial cost.
- Replace formatting StringBuilder with ref struct and stack allocation. Avoids lots of allocation and associated throughput costs.
- Improve perf of 'D' formatting of 32-bit and 64-bit integers.
- Remove array allocations accessing NumberFormatInfo props.
- Accessing array properties like PercentGroupSizes clones the corresponding field. That's unnecessary here, as we don't mutate the array.
- Remove int[] allocation from NumberToStringFormat. Span makes it easy to start with stack space and grow to an allocated array as needed.
- Improve perf of hex formatting of integers. Including removing some sizable allocations.
- Manually inline several hot functions called in only one place.
- Tweak some range comparisons in ParseFormatSpecifier.
- Avoid large stackallocs in NumberToString{Fixed}. It's incurring non-trivial overheads.
- Tweak perf of ValueStringBuilder. In particular, make Append(string) faster for the single-char case, which is extremely common in integer formatting due to its prevalence in strings in NumberFormatInfo.