Skip to content

[Perf] BigInteger formatting performance regression in .NET 9 #111708

@xakep139

Description

@xakep139

Description

After reading Performance Improvements in .NET 9 related to BigInteger, I've noticed a comment indicating that C# has poor performance compared to other programming languages in terms of big integer calculations. After quick investigation, it turned out that half of the time in https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/edigits/1.cs is spent on formatting of a big integer. On .NET 8 it's done twice as fast, even though there were performance optimizations made in .NET 9.

Here's a benchmark code that shows the issue:

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Numerics;

BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);

[MemoryDiagnoser(false)]
[HideColumns("Job", "Error", "StdDev", "Median", "RatioSD")]
public class Tests
{
    private char[] _dest = new char[1_000_000];

    private BigInteger _value =
        BigInteger.Pow(BigInteger.Parse(string.Concat(Enumerable.Repeat("1234567890", 30))), 1_000);

    [Benchmark(Baseline = true)]
    public string Stringify() => _value.ToString();

    [Benchmark]
    public bool TryFormat() => _value.TryFormat(_dest, out _);
}

Configuration

BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.2894)
AMD Ryzen 9 4900H with Radeon Graphics, 1 CPU, 16 logical and 8 physical cores
.NET SDK 9.0.102
  [Host]     : .NET 8.0.12 (8.0.1224.60305), X64 RyuJIT AVX2
  Job-TESATW : .NET 8.0.12 (8.0.1224.60305), X64 RyuJIT AVX2
  Job-VBXNCI : .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2

Regression?

Yes. The same code on .NET 8 executes ~3 times faster (but with much more memory being allocated).

Data

| Method    | Runtime  | Mean    | Ratio | Allocated | Alloc Ratio |
|---------- |--------- |--------:|------:|----------:|------------:|
| Stringify | .NET 8.0 | 1.009 s |  1.00 | 1303.9 KB |       1.000 |
| TryFormat | .NET 8.0 | 1.005 s |  1.00 | 719.71 KB |       0.552 |
| Stringify | .NET 9.0 | 3.657 s |  3.62 | 585.23 KB |       0.449 |
| TryFormat | .NET 9.0 | 3.657 s |  3.63 |   1.05 KB |       0.001 |

Analysis

This regression might be caused by the #100181, but I haven't thoroughly tested that regression on older codebase.
The regression is reproduced on really big integers (order of magnitude 1000+).

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Numericsin-prThere is an active PR which will close this issue when it is mergedtenet-performancePerformance related issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions