Skip to content

Commit

Permalink
Use ArrayPool<int> instead of ArrayPool<uint>.
Browse files Browse the repository at this point in the history
  • Loading branch information
jfd16 committed Feb 5, 2021
1 parent 7ea7474 commit 5657cfc
Showing 1 changed file with 25 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;

namespace System.Numerics
Expand Down Expand Up @@ -416,11 +417,11 @@ private static bool HexNumberToBigInteger(ref BigNumberBuffer number, out int si
bool isNegative = HexConverter.FromChar(number.digits[0]) >= 8;
uint partialValue = (isNegative && partialDigitCount > 0) ? 0xFFFFFFFFu : 0;

uint[]? arrayFromPool = null;
int[]? arrayFromPool = null;

Span<uint> bitsBuffer = (blockCount <= BigInteger.StackallocUInt32Limit)
? stackalloc uint[blockCount]
: (arrayFromPool = ArrayPool<uint>.Shared.Rent(blockCount)).AsSpan(0, blockCount);
Span<int> bitsBuffer = (blockCount <= BigInteger.StackallocUInt32Limit)
? stackalloc int[blockCount]
: (arrayFromPool = ArrayPool<int>.Shared.Rent(blockCount)).AsSpan(0, blockCount);

int bitsBufferPos = blockCount - 1;

Expand All @@ -443,7 +444,7 @@ private static bool HexNumberToBigInteger(ref BigNumberBuffer number, out int si
}
else if (blockCountNoLeadingZeros == 1)
{
sign = (int)bitsBuffer[0];
sign = bitsBuffer[0];
bits = null;

if ((!isNegative && sign < 0) || sign == int.MinValue)
Expand All @@ -455,7 +456,7 @@ private static bool HexNumberToBigInteger(ref BigNumberBuffer number, out int si
else
{
sign = isNegative ? -1 : 1;
bits = bitsBuffer.Slice(0, blockCountNoLeadingZeros).ToArray();
bits = MemoryMarshal.Cast<int, uint>(bitsBuffer).Slice(0, blockCountNoLeadingZeros).ToArray();

if (isNegative)
NumericsHelpers.DangerousMakeTwosComplement(bits);
Expand All @@ -466,10 +467,10 @@ private static bool HexNumberToBigInteger(ref BigNumberBuffer number, out int si
finally
{
if (arrayFromPool != null)
ArrayPool<uint>.Shared.Return(arrayFromPool);
ArrayPool<int>.Shared.Return(arrayFromPool);
}

void ProcessChunk(ReadOnlySpan<char> chunkDigits, Span<uint> _bitsBuffer)
void ProcessChunk(ReadOnlySpan<char> chunkDigits, Span<int> _bitsBuffer)
{
for (int i = 0; i < chunkDigits.Length; i++)
{
Expand All @@ -485,7 +486,7 @@ void ProcessChunk(ReadOnlySpan<char> chunkDigits, Span<uint> _bitsBuffer)

if (partialDigitCount == DigitsPerBlock)
{
_bitsBuffer[bitsBufferPos] = partialValue;
_bitsBuffer[bitsBufferPos] = (int)partialValue;
bitsBufferPos--;
partialValue = 0;
partialDigitCount = 0;
Expand All @@ -499,10 +500,10 @@ private static bool NumberToBigInteger(ref BigNumberBuffer number, out int sign,
sign = 0;
bits = null;

Span<uint> stackBuffer = stackalloc uint[BigInteger.StackallocUInt32Limit];
Span<uint> currentBuffer = stackBuffer;
Span<int> stackBuffer = stackalloc int[BigInteger.StackallocUInt32Limit];
Span<int> currentBuffer = stackBuffer;
int currentBufferSize = 0;
uint[]? arrayFromPool = null;
int[]? arrayFromPool = null;

uint partialValue = 0;
int partialDigitCount = 0;
Expand Down Expand Up @@ -542,24 +543,24 @@ private static bool NumberToBigInteger(ref BigNumberBuffer number, out int sign,
}
else if (currentBufferSize == 1 && currentBuffer[0] <= int.MaxValue)
{
sign = (int)(number.sign ? -currentBuffer[0] : currentBuffer[0]);
sign = number.sign ? -currentBuffer[0] : currentBuffer[0];
bits = null;
}
else
{
sign = number.sign ? -1 : 1;
bits = currentBuffer.Slice(0, currentBufferSize).ToArray();
bits = MemoryMarshal.Cast<int, uint>(currentBuffer).Slice(0, currentBufferSize).ToArray();
}

return true;
}
finally
{
if (arrayFromPool != null)
ArrayPool<uint>.Shared.Return(arrayFromPool);
ArrayPool<int>.Shared.Return(arrayFromPool);
}

bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> _currentBuffer)
bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<int> _currentBuffer)
{
int remainingIntDigitCount = Math.Max(numberScale - totalDigitCount, 0);
ReadOnlySpan<char> intDigitsSpan = chunkDigits.Slice(0, Math.Min(remainingIntDigitCount, chunkDigits.Length));
Expand Down Expand Up @@ -597,15 +598,15 @@ bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> _currentBuffer)
return true;
}

void MultiplyAdd(ref Span<uint> _currentBuffer, uint multiplier, uint addValue)
void MultiplyAdd(ref Span<int> _currentBuffer, uint multiplier, uint addValue)
{
Span<uint> curBits = _currentBuffer.Slice(0, currentBufferSize);
Span<int> curBits = _currentBuffer.Slice(0, currentBufferSize);
uint carry = addValue;

for (int i = 0; i < curBits.Length; i++)
{
ulong p = (ulong)multiplier * curBits[i] + carry;
curBits[i] = (uint)p;
ulong p = (ulong)multiplier * (uint)curBits[i] + carry;
curBits[i] = (int)p;
carry = (uint)(p >> 32);
}

Expand All @@ -614,17 +615,17 @@ void MultiplyAdd(ref Span<uint> _currentBuffer, uint multiplier, uint addValue)

if (currentBufferSize == _currentBuffer.Length)
{
uint[]? arrayToReturn = arrayFromPool;
int[]? arrayToReturn = arrayFromPool;

arrayFromPool = ArrayPool<uint>.Shared.Rent(checked(currentBufferSize * 2));
arrayFromPool = ArrayPool<int>.Shared.Rent(checked(currentBufferSize * 2));
_currentBuffer.CopyTo(arrayFromPool);
_currentBuffer = arrayFromPool;

if (arrayToReturn != null)
ArrayPool<uint>.Shared.Return(arrayToReturn);
ArrayPool<int>.Shared.Return(arrayToReturn);
}

_currentBuffer[currentBufferSize] = carry;
_currentBuffer[currentBufferSize] = (int)carry;
currentBufferSize++;
}
}
Expand Down

0 comments on commit 5657cfc

Please sign in to comment.