Description
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+).