mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-09-14 19:16:17 +00:00
uucore: num_parser: Optimize bigdecimal create when exponent is 0
Makes creating float number without an exponent part quite a bit faster. Saves about 9% speed in sort -g.
This commit is contained in:
parent
3b18316337
commit
7457a76f40
1 changed files with 17 additions and 12 deletions
|
@ -67,15 +67,15 @@ impl Base {
|
||||||
&self,
|
&self,
|
||||||
str: &'a str,
|
str: &'a str,
|
||||||
digits: Option<BigUint>,
|
digits: Option<BigUint>,
|
||||||
) -> (Option<BigUint>, u64, &'a str) {
|
) -> (Option<BigUint>, i64, &'a str) {
|
||||||
let mut digits: Option<BigUint> = digits;
|
let mut digits: Option<BigUint> = digits;
|
||||||
let mut count: u64 = 0;
|
let mut count: i64 = 0;
|
||||||
let mut rest = str;
|
let mut rest = str;
|
||||||
|
|
||||||
// Doing operations on BigUint is really expensive, so we do as much as we
|
// Doing operations on BigUint is really expensive, so we do as much as we
|
||||||
// can on u64, then add them to the BigUint.
|
// can on u64, then add them to the BigUint.
|
||||||
let mut digits_tmp: u64 = 0;
|
let mut digits_tmp: u64 = 0;
|
||||||
let mut count_tmp: u64 = 0;
|
let mut count_tmp: i64 = 0;
|
||||||
let mut mul_tmp: u64 = 1;
|
let mut mul_tmp: u64 = 1;
|
||||||
while let Some(d) = rest.chars().next().and_then(|c| self.digit(c)) {
|
while let Some(d) = rest.chars().next().and_then(|c| self.digit(c)) {
|
||||||
(digits_tmp, count_tmp, mul_tmp) = (
|
(digits_tmp, count_tmp, mul_tmp) = (
|
||||||
|
@ -290,7 +290,7 @@ impl ExtendedParser for ExtendedBigDecimal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_digits(base: Base, str: &str, fractional: bool) -> (Option<BigUint>, u64, &str) {
|
fn parse_digits(base: Base, str: &str, fractional: bool) -> (Option<BigUint>, i64, &str) {
|
||||||
// Parse the integral part of the number
|
// Parse the integral part of the number
|
||||||
let (digits, rest) = base.parse_digits(str);
|
let (digits, rest) = base.parse_digits(str);
|
||||||
|
|
||||||
|
@ -472,7 +472,7 @@ fn construct_extended_big_decimal<'a>(
|
||||||
digits: BigUint,
|
digits: BigUint,
|
||||||
negative: bool,
|
negative: bool,
|
||||||
base: Base,
|
base: Base,
|
||||||
scale: u64,
|
scale: i64,
|
||||||
exponent: BigInt,
|
exponent: BigInt,
|
||||||
) -> Result<ExtendedBigDecimal, ExtendedParserError<'a, ExtendedBigDecimal>> {
|
) -> Result<ExtendedBigDecimal, ExtendedParserError<'a, ExtendedBigDecimal>> {
|
||||||
if digits == BigUint::zero() {
|
if digits == BigUint::zero() {
|
||||||
|
@ -490,14 +490,19 @@ fn construct_extended_big_decimal<'a>(
|
||||||
let bd = if scale == 0 && exponent.is_zero() {
|
let bd = if scale == 0 && exponent.is_zero() {
|
||||||
BigDecimal::from_bigint(signed_digits, 0)
|
BigDecimal::from_bigint(signed_digits, 0)
|
||||||
} else if base == Base::Decimal {
|
} else if base == Base::Decimal {
|
||||||
let new_scale = -exponent + scale;
|
if exponent.is_zero() {
|
||||||
|
// Optimization: Converting scale to Bigint and back is relatively slow.
|
||||||
// BigDecimal "only" supports i64 scale.
|
BigDecimal::from_bigint(signed_digits, scale)
|
||||||
// Note that new_scale is a negative exponent: large positive value causes an underflow, large negative values an overflow.
|
|
||||||
if let Some(new_scale) = new_scale.to_i64() {
|
|
||||||
BigDecimal::from_bigint(signed_digits, new_scale)
|
|
||||||
} else {
|
} else {
|
||||||
return Err(make_error(new_scale.is_negative(), negative));
|
let new_scale = -exponent + scale;
|
||||||
|
|
||||||
|
// BigDecimal "only" supports i64 scale.
|
||||||
|
// Note that new_scale is a negative exponent: large positive value causes an underflow, large negative values an overflow.
|
||||||
|
if let Some(new_scale) = new_scale.to_i64() {
|
||||||
|
BigDecimal::from_bigint(signed_digits, new_scale)
|
||||||
|
} else {
|
||||||
|
return Err(make_error(new_scale.is_negative(), negative));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if base == Base::Hexadecimal {
|
} else if base == Base::Hexadecimal {
|
||||||
// pow "only" supports u32 values, just error out if given more than 2**32 fractional digits.
|
// pow "only" supports u32 values, just error out if given more than 2**32 fractional digits.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue