Skip to content

Improve the performance of BigInteger.{Max|Min}Magnitude/Abs & fix a edge case of TryParse - #105570

Merged
tannergooding merged 10 commits into
dotnet:mainfrom
karakasa:bigint-perf-improv
Sep 16, 2025
Merged

Improve the performance of BigInteger.{Max|Min}Magnitude/Abs & fix a edge case of TryParse#105570
tannergooding merged 10 commits into
dotnet:mainfrom
karakasa:bigint-perf-improv

Conversation

@karakasa

@karakasa karakasa commented Jul 26, 2024

Copy link
Copy Markdown
Contributor

Close #105324

The PR is to:

  • Improve worst-case performance of BigInteger.{Max|Min}Magnitude by changing multiple comparison operators to a single CompareTo call
  • Improve perf of BigInteger.Abs() by refactoring code and making the method branchless.
  • Fix a bug where BigInteger.TryParse still throws instead of returning false.
    • PS: I wrote an OuterLoop test covering this but it would take 1.5~2GB which may unstablize the testing environment. Feel free to notify me if you think the test should be removed. The bug is on a very rare path.
Method Toolchain Length Mean Error StdDev Ratio RatioSD
Abs main 2 2.902 ns 0.0061 ns 0.0048 ns 1.00 0.00
Abs pr 2 1.367 ns 0.0071 ns 0.0059 ns 0.47 0.00
MaxMagnitude_WorstPath main 2 11.603 ns 0.0660 ns 0.0585 ns 1.00 0.00
MaxMagnitude_WorstPath pr 2 3.553 ns 0.0092 ns 0.0081 ns 0.31 0.00
Abs main 16 3.183 ns 0.0133 ns 0.0118 ns 1.00 0.00
Abs pr 16 1.173 ns 0.0433 ns 0.0405 ns 0.37 0.01
MaxMagnitude_WorstPath main 16 14.485 ns 0.3156 ns 0.5690 ns 1.00 0.00
MaxMagnitude_WorstPath pr 16 6.758 ns 0.0230 ns 0.0204 ns 0.46 0.02
Abs main 256 2.912 ns 0.0106 ns 0.0099 ns 1.00 0.00
Abs pr 256 1.138 ns 0.0032 ns 0.0027 ns 0.39 0.00
MaxMagnitude_WorstPath main 256 56.795 ns 0.2398 ns 0.2243 ns 1.00 0.00
MaxMagnitude_WorstPath pr 256 35.709 ns 0.0808 ns 0.0675 ns 0.63 0.00
Abs main 4096 3.007 ns 0.0355 ns 0.0277 ns 1.00 0.00
Abs pr 4096 1.146 ns 0.0181 ns 0.0161 ns 0.38 0.01
MaxMagnitude_WorstPath main 4096 547.978 ns 0.7053 ns 0.5889 ns 1.00 0.00
MaxMagnitude_WorstPath pr 4096 479.951 ns 0.8376 ns 0.7425 ns 0.88 0.00

Improved performance of BigInteger.{Max|Min}Magnitude/Abs/operator-

Co-Authored-By: PetSerAl <17184058+petseral@users.noreply.github.com>
@ghost ghost added the area-System.Numerics label Jul 26, 2024
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Jul 26, 2024
@karakasa karakasa changed the title Improve the performance of BigInteger.{Max|Min}Magnitude/Abs/operator- Improve the performance of BigInteger.{Max|Min}Magnitude/Abs Jul 27, 2024
@tannergooding tannergooding added this to the 10.0.0 milestone Jul 27, 2024
@karakasa
karakasa marked this pull request as ready for review July 28, 2024 08:54
Comment thread src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs Outdated
Comment thread src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs Outdated
@LEI-Hongfaan

Copy link
Copy Markdown
Contributor

Interesting.

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private BigInteger(int n, uint[]? rgu, [ConstantExpected] bool noLengthCheck)
        {
            if (noLengthCheck && (rgu is not null) && (rgu.Length > MaxLength))
            {
                ThrowHelper.ThrowOverflowException();
            }

            _sign = n;
            _bits = rgu;

            AssertValid();
        }

https://github.com/LEI-Hongfaan/dotnet-runtime/blob/f49abbbd68a222c0ce77f80aa19ecd53630505e7/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs#L492

And

                    return new BigInteger(-1, buffer, noLengthCheck: true);

https://github.com/LEI-Hongfaan/dotnet-runtime/blob/f49abbbd68a222c0ce77f80aa19ecd53630505e7/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs#L1675

Maybe we can have...

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        internal BigInteger(int n, uint[]? rgu, [ConstantExpected] bool noLengthCheck = false)

@karakasa

karakasa commented Jul 30, 2024

Copy link
Copy Markdown
Contributor Author
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        internal BigInteger(int n, uint[]? rgu, [ConstantExpected] bool noLengthCheck = false)

I tend not to break any existing method, as long as it's not private. ConstantExpected is a good idea.

@huoyaoyuan

Copy link
Copy Markdown
Member

I tend not to break any existing method, as long as it's not private.

There should not be difference between private and internal in this case. The internal accessors would be dedicated utility types for BigInteger, like the BigIntegerCalculator.

@karakasa karakasa changed the title Improve the performance of BigInteger.{Max|Min}Magnitude/Abs Improve the performance of BigInteger.{Max|Min}Magnitude/Abs & fix a edge case of TryParse Jul 30, 2024
@jeffhandley

Copy link
Copy Markdown
Member

/azp run runtime-libraries-coreclr outerloop

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jeffhandley

Copy link
Copy Markdown
Member

@tannergooding This is a more targeted change that seems worthwhile to bring in to .NET 11.

@jeffhandley jeffhandley modified the milestones: 10.0.0, 11.0.0 Sep 4, 2025
@tannergooding
tannergooding enabled auto-merge (squash) September 16, 2025 19:10
@tannergooding
tannergooding merged commit 116db00 into dotnet:main Sep 16, 2025
86 of 88 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 17, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Numerics community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BigInteger.MaxMagnitude

6 participants