Skip to content

Commit a9942c5

Browse files
committed
to use ArrayPool<int>.Shared.Rent for newBuffer allocation
1 parent c3903db commit a9942c5

File tree

1 file changed

+22
-4
lines changed
  • src/libraries/System.Runtime.Numerics/src/System/Numerics

1 file changed

+22
-4
lines changed

src/libraries/System.Runtime.Numerics/src/System/Numerics/BigNumber.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ private static bool NumberToBigInteger(ref BigNumberBuffer number, out BigIntege
510510
int currentBufferSize = 0;
511511

512512
int[]? arrayFromPool = null;
513+
int[]? rentedBuffer = null;
513514

514515
int totalDigitCount = 0;
515516
int numberScale = number.scale;
@@ -607,11 +608,24 @@ bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> currentBuffer)
607608
int bufferSize = (totalDigitCount + MaxPartialDigits - 1) / MaxPartialDigits;
608609

609610
Span<uint> buffer = new uint[bufferSize];
611+
rentedBuffer = ArrayPool<int>.Shared.Rent(bufferSize);
612+
Span<uint> newBuffer = MemoryMarshal.Cast<int, uint>(rentedBuffer);
613+
newBuffer.Clear();
614+
615+
// To ensure finally stored in newBuffer is the borrowed buffer.
616+
int blockSize = 1;
617+
do
618+
{
619+
Span<uint> tmp = buffer;
620+
buffer = newBuffer;
621+
newBuffer = tmp;
622+
blockSize *= 2;
623+
} while (blockSize < bufferSize);
610624

611625
// Separate every MaxPartialDigits digits and store them in the buffer.
612626
// Buffers are treated as little-endian. That means, the array { 234567890, 1 }
613627
// represents the number 1234567890.
614-
int bufferIndex = buffer.Length - 1;
628+
int bufferIndex = bufferSize - 1;
615629
uint currentBlock = 0;
616630
int shiftUntil = (totalDigitCount - 1) % MaxPartialDigits;
617631
int remainingIntDigitCount = totalDigitCount;
@@ -658,13 +672,11 @@ bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> currentBuffer)
658672

659673
unsafe
660674
{
661-
Span<uint> newBuffer = new uint[bufferSize];
662-
663675
arrayFromPool = ArrayPool<int>.Shared.Rent(1);
664676
Span<uint> multiplier = MemoryMarshal.Cast<int, uint>(arrayFromPool);
665677
multiplier[0] = TenPowMaxPartial;
666678

667-
int blockSize = 1;
679+
blockSize = 1;
668680
while (true)
669681
{
670682
fixed (uint* bufPtr = buffer, newBufPtr = newBuffer, mulPtr = multiplier)
@@ -739,6 +751,8 @@ bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> currentBuffer)
739751
}
740752
}
741753

754+
Debug.Assert(MemoryMarshal.Cast<int, uint>(rentedBuffer) == newBuffer);
755+
742756
// shrink buffer to the currently used portion.
743757
// First, calculate the rough size of the buffer from the ratio that the number
744758
// of digits follows. Then, shrink the size until there is no more space left.
@@ -794,6 +808,10 @@ bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> currentBuffer)
794808
{
795809
ArrayPool<int>.Shared.Return(arrayFromPool);
796810
}
811+
if (rentedBuffer != null)
812+
{
813+
ArrayPool<int>.Shared.Return(rentedBuffer);
814+
}
797815
}
798816

799817
void MultiplyAdd(ref Span<uint> currentBuffer, uint multiplier, uint addValue)

0 commit comments

Comments
 (0)