Skip to content

Conversation

kzrnm
Copy link
Contributor

@kzrnm kzrnm commented Feb 28, 2025

This PR is a refactored version of #112632.

Benchmark


BenchmarkDotNet v0.13.12, Windows 11 (10.0.26100.3194)
13th Gen Intel Core i5-13500, 1 CPU, 20 logical and 14 physical cores
.NET SDK 10.0.100-preview.3.25125.5
  [Host]     : .NET 10.0.0 (10.0.25.12411), X64 RyuJIT AVX2
  Job-MGDTRH : .NET 10.0.0 (42.42.42.42424), X64 RyuJIT AVX2
  Job-TRYYFZ : .NET 10.0.0 (42.42.42.42424), X64 RyuJIT AVX2
  Job-BFYRFS : .NET 10.0.0 (42.42.42.42424), X64 RyuJIT AVX2


Method Toolchain Mean Ratio Gen0 Gen1 Gen2 Allocated Alloc Ratio
PositiveLeftShift \main\corerun.exe 13.150 ms 1.00 62.5000 62.5000 62.5000 33 MB 1.00
PositiveLeftShift \vectorize\corerun.exe 6.654 ms 0.48 156.2500 156.2500 156.2500 33 MB 1.00
PositiveLeftShift \scalar\corerun.exe 8.763 ms 0.64 156.2500 156.2500 156.2500 33 MB 1.00
NegativeLeftShift \main\corerun.exe 12.914 ms 1.00 78.1250 78.1250 78.1250 33 MB 1.00
NegativeLeftShift \vectorize\corerun.exe 6.559 ms 0.50 156.2500 156.2500 156.2500 33 MB 1.00
NegativeLeftShift \scalar\corerun.exe 8.794 ms 0.68 156.2500 156.2500 156.2500 33 MB 1.00
PositiveRightShift \main\corerun.exe 15.399 ms 1.00 125.0000 125.0000 125.0000 31 MB 1.00
PositiveRightShift \vectorize\corerun.exe 9.417 ms 0.61 187.5000 187.5000 187.5000 31 MB 1.00
PositiveRightShift \scalar\corerun.exe 11.450 ms 0.74 187.5000 187.5000 187.5000 31 MB 1.00
NegativeRightShift \main\corerun.exe 19.945 ms 1.00 125.0000 125.0000 125.0000 31 MB 1.00
NegativeRightShift \vectorize\corerun.exe 9.426 ms 0.48 187.5000 187.5000 187.5000 31 MB 1.00
NegativeRightShift \scalar\corerun.exe 11.648 ms 0.58 187.5000 187.5000 187.5000 31 MB 1.00
PositiveUnsignedRightShift \main\corerun.exe 14.067 ms 1.00 125.0000 125.0000 125.0000 31 MB 1.00
PositiveUnsignedRightShift \vectorize\corerun.exe 9.431 ms 0.67 187.5000 187.5000 187.5000 31 MB 1.00
PositiveUnsignedRightShift \scalar\corerun.exe 11.628 ms 0.83 187.5000 187.5000 187.5000 31 MB 1.00
NegativeUnsignedRightShift \main\corerun.exe 16.347 ms 1.00 125.0000 125.0000 125.0000 31 MB 1.00
NegativeUnsignedRightShift \vectorize\corerun.exe 11.230 ms 0.69 187.5000 187.5000 187.5000 31 MB 1.00
NegativeUnsignedRightShift \scalar\corerun.exe 13.608 ms 0.83 187.5000 187.5000 187.5000 31 MB 1.00
PositiveRotateLeft \main\corerun.exe 13.674 ms 1.00 125.0000 125.0000 125.0000 32 MB 1.00
PositiveRotateLeft \vectorize\corerun.exe 10.775 ms 0.79 187.5000 187.5000 187.5000 32 MB 1.00
PositiveRotateLeft \scalar\corerun.exe 13.057 ms 0.96 187.5000 187.5000 187.5000 32 MB 1.00
NegativeRotateLeft \main\corerun.exe 18.040 ms 1.00 125.0000 125.0000 125.0000 32 MB 1.00
NegativeRotateLeft \vectorize\corerun.exe 14.679 ms 0.83 187.5000 187.5000 187.5000 32 MB 1.00
NegativeRotateLeft \scalar\corerun.exe 17.039 ms 0.94 187.5000 187.5000 187.5000 32 MB 1.00
PositiveRotateRight \main\corerun.exe 13.671 ms 1.00 125.0000 125.0000 125.0000 32 MB 1.00
PositiveRotateRight \vectorize\corerun.exe 10.651 ms 0.78 187.5000 187.5000 187.5000 32 MB 1.00
PositiveRotateRight \scalar\corerun.exe 13.071 ms 0.96 187.5000 187.5000 187.5000 32 MB 1.00
NegativeRotateRight \main\corerun.exe 16.000 ms 1.00 125.0000 125.0000 125.0000 32 MB 1.00
NegativeRotateRight \vectorize\corerun.exe 12.632 ms 0.79 187.5000 187.5000 187.5000 32 MB 1.00
NegativeRotateRight \scalar\corerun.exe 14.861 ms 0.93 187.5000 187.5000 187.5000 32 MB 1.00

<details>

<summary>benchmark code</summary>

```cs
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using System.Numerics;

[MemoryDiagnoser(false)]
[HideColumns("Job", "Error", "StdDev", "Median", "RatioSD")]
public class ShiftTest
{
    const int shiftSize = (1 << 23) + 13;
    BigInteger positive, negative;

    [GlobalSetup]
    public void Setup()
    {
        var bytes = new byte[1 << 25];
        new Random(227).NextBytes(bytes);
        positive = new BigInteger(bytes, isUnsigned: true);
        negative = -positive;
    }

    [Benchmark] public BigInteger PositiveLeftShift() => positive << shiftSize;
    [Benchmark] public BigInteger NegativeLeftShift() => negative << shiftSize;

    [Benchmark] public BigInteger PositiveRightShift() => positive >> shiftSize;
    [Benchmark] public BigInteger NegativeRightShift() => negative >> shiftSize;

    [Benchmark] public BigInteger PositiveUnsignedRightShift() => positive >>> shiftSize;
    [Benchmark] public BigInteger NegativeUnsignedRightShift() => negative >>> shiftSize;

    [Benchmark] public BigInteger PositiveRotateLeft() => BigInteger.RotateLeft(positive, shiftSize);
    [Benchmark] public BigInteger NegativeRotateLeft() => BigInteger.RotateLeft(negative, shiftSize);

    [Benchmark] public BigInteger PositiveRotateRight() => BigInteger.RotateRight(positive, shiftSize);
    [Benchmark] public BigInteger NegativeRotateRight() => BigInteger.RotateRight(negative, shiftSize);
}

@ghost ghost added the area-System.Numerics label Feb 28, 2025
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Feb 28, 2025
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.

@jeffhandley
Copy link
Member

@tannergooding I know we've talked (for a long time) about substantial overhauls (rewrites) of how BigInteger is implemented, and I have been sitting on this PR (sorry, @kzrnm) for a long time because I've been unsure if we should take incremental but still sizeable changes. I'm inclined to accept this change though, even if we do end up doing more substantial work later. What do you think?

@tannergooding tannergooding merged commit a29c8a9 into dotnet:main Sep 17, 2025
88 checks passed
@kzrnm kzrnm deleted the BigIntegerShift branch September 17, 2025 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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.

4 participants