mhogrefe / malachite

An arbitrary-precision arithmetic library for Rust.
GNU Lesser General Public License v3.0
448 stars 17 forks source link

Small number parsing fast path #27

Closed konstin closed 10 months ago

konstin commented 1 year ago

We found that replacing

let value = number.as_str().parse::<BigInt>().unwrap();

with

// Optimization: `Natural` and thereby `Integer` add up digits from bytes to convert
// from string. This is much less efficient than the highly optimized std
// string-to-number parser and we know that most numbers are small.
// i32::MAX is 2147483647 (10 digits), so all 9 digit numbers are representable as
// i32. We can't guarantee that `32_bit_limbs` isn't set, so we limit ourselves to
// i32 instead of i64.
let value = if number.as_str().len() < 10 {
    Integer::from(i32::from_str(number.as_str()).unwrap())
} else {
   Integer::from_str(number.as_str()).unwrap()
};

for cases where we know that radix is 10 gives a significant speedup for our use case (parsing a lot of number which are generally small). It would be great if malachite would natively contain such an optimization, which could be extended by e.g. checking whether the first by is -.

mhogrefe commented 1 year ago

Thanks for pointing this out. I'll include this optimization in the next release.

mhogrefe commented 10 months ago

Fixed in 0.4.3.

See https://github.com/mhogrefe/malachite/blob/v0.4.3/malachite-nz/src/natural/conversion/string/from_string.rs#L204; that is the optimization for Naturals, and the Integer and Rational parsing code forwards to it.

mhogrefe commented 10 months ago

Sorry, v0.4.3 had some wrong dependencies. Please use v0.4.4 instead.