-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
System.Numerics.BigInteger
has a number of methods that look for the first zero (or first non-zero) element. This is usually done by looping through the span/array. It seems that most of them can be rewritten by Span.LastIndexOfAnyExcept()
(or similar methods) - this method can be faster than plain loop. Isolated tests show improvement up to 8 times on modern x64 (but any distinct case need clarification).
Click here to expand and show examples
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 424 to 427 in bed0ec0
// Pack _bits to remove any wasted space after the twos complement | |
int len = val.Length - 1; | |
while (len >= 0 && val[len] == 0) len--; | |
len++; |
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 503 to 505 in bed0ec0
// Try to conserve space as much as possible by checking for wasted leading span entries | |
// sometimes the span has leading zeros from bit manipulation operations & and ^ | |
for (len = value.Length; len > 0 && value[len - 1] == 0; len--); |
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 544 to 545 in bed0ec0
// Try to conserve space as much as possible by checking for wasted leading span entries | |
while (dwordCount > 0 && value[dwordCount - 1] == 0) dwordCount--; |
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 589 to 591 in bed0ec0
// Pack _bits to remove any wasted space after the twos complement | |
int len = value.Length; | |
while (len > 0 && value[len - 1] == 0) len--; |
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 641 to 645 in bed0ec0
while (--iu >= 0) | |
{ | |
if (_bits[iu] != 0) | |
return false; | |
} |
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 1387 to 1390 in bed0ec0
while (bits[nonZeroDwordIndex] == 0U) | |
{ | |
nonZeroDwordIndex++; | |
} |
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 1545 to 1550 in bed0ec0
// Find highest significant byte and ensure high bit is 0 if positive, 1 if negative | |
int msb = buffer.Length - 2; | |
while (msb > 0 && buffer[msb] == highDWord) | |
{ | |
msb--; | |
} |
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 3093 to 3101 in bed0ec0
// Check the rest of the bits (if present) | |
for (int i = bitsArrayLength - 2; i >= 0; i--) | |
{ | |
// bits array is always non-null when bitsArrayLength >= 2 | |
if (bits![i] == 0) | |
continue; | |
return bitLength; | |
} |
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 3540 to 3544 in bed0ec0
for (int i = 1; (part == 0) && (i < value._bits.Length); i++) | |
{ | |
part = value._bits[i]; | |
result += (sizeof(uint) * 8); | |
} |
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 3599 to 3606 in bed0ec0
for (int index = 0; index < bits.Length - 1; index++) | |
{ | |
if (bits[index] != 0) | |
{ | |
part -= 1; | |
break; | |
} | |
} |
runtime/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
Lines 3840 to 3847 in bed0ec0
for (int index = 0; index < bits.Length - 1; index++) | |
{ | |
if (bits[index] != 0) | |
{ | |
part -= 1; | |
break; | |
} | |
} |
May be I miss some of them. May be some of them shouldn't use span memory extension methods.
Configuration
Current main branch
Regression?
No
Data
Will be provided
Analysis
Will be provided