From cf0cb0114175fb5e4a92d909026cadb6ae7fa032 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sat, 2 May 2020 10:36:23 -0400 Subject: [PATCH] further optimize formatting of numbers grass differs from rsass in that all numbers are bigints. this makes our fomatting of numbers 6x slower than rsass and barely faster than node-sass. ideally in the future, we would just use plain float formatting. i've learned that dart-sass no longer configures precision as a cli flag, so there is potentially some manual loop unrolling or optimizations we could make knowing that all numbers must be a max of 10 digits. the next release of num_rational should contain an implementation of to_f64() for BigRational, so that may solve our problems. --- src/value/number.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/value/number.rs b/src/value/number.rs index 66dcce1..28c7e66 100644 --- a/src/value/number.rs +++ b/src/value/number.rs @@ -170,19 +170,20 @@ impl fmt::Debug for Number { impl Display for Number { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut whole = self.val.to_integer().abs(); - let mut frac = self.val.fract(); - let mut dec = String::with_capacity(if frac.is_zero() { 0 } else { PRECISION + 1 }); - if !frac.is_zero() { + let has_decimal = !self.val.denom().is_one(); + let mut frac = self.val.fract().abs(); + let mut dec = String::with_capacity(if !has_decimal { 0 } else { PRECISION + 1 }); + if has_decimal { for _ in 0..(PRECISION - 1) { frac *= BigInt::from(10); - write!(dec, "{}", frac.to_integer().abs())?; + write!(dec, "{}", frac.to_integer())?; frac = frac.fract(); if frac.is_zero() { break; } } if !frac.is_zero() { - let end = (frac * BigInt::from(10)).round().abs().to_integer(); + let end = (frac * BigInt::from(10)).round().to_integer(); if end == BigInt::from(10) { loop { match dec.pop() {