aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2020-03-03 10:17:34 -0800
committerPaul Eggert2020-03-03 10:20:33 -0800
commitb48142ba190c5b490685af961af1f0f4fd5440ae (patch)
tree99828fdb2da84b04b3dcbbf90816de2c4d3cd325 /src
parent5e229f88f946c9c246966defeb629965f65d9549 (diff)
downloademacs-b48142ba190c5b490685af961af1f0f4fd5440ae.tar.gz
emacs-b48142ba190c5b490685af961af1f0f4fd5440ae.zip
Time division speedups
* src/timefns.c (frac_to_double) [FASTER_TIMEFNS]: Prefer intmax_t division or double division to mpz division if they also yield the correctly rounded result.
Diffstat (limited to 'src')
-rw-r--r--src/timefns.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/timefns.c b/src/timefns.c
index b96a6cb8875..0aa8775f9ff 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -569,16 +569,22 @@ timespec_to_lisp (struct timespec t)
569static double 569static double
570frac_to_double (Lisp_Object numerator, Lisp_Object denominator) 570frac_to_double (Lisp_Object numerator, Lisp_Object denominator)
571{ 571{
572 intmax_t intmax_numerator; 572 intmax_t intmax_numerator, intmax_denominator;
573 if (FASTER_TIMEFNS && EQ (denominator, make_fixnum (1)) 573 if (FASTER_TIMEFNS
574 && integer_to_intmax (numerator, &intmax_numerator)) 574 && integer_to_intmax (numerator, &intmax_numerator)
575 return intmax_numerator; 575 && integer_to_intmax (denominator, &intmax_denominator)
576 && ! INT_DIVIDE_OVERFLOW (intmax_numerator, intmax_denominator)
577 && intmax_numerator % intmax_denominator == 0)
578 return intmax_numerator / intmax_denominator;
576 579
577 mpz_t const *n = bignum_integer (&mpz[0], numerator); 580 mpz_t const *n = bignum_integer (&mpz[0], numerator);
578 mpz_t const *d = bignum_integer (&mpz[1], denominator); 581 mpz_t const *d = bignum_integer (&mpz[1], denominator);
579 ptrdiff_t ndig = mpz_sizeinbase (*n, FLT_RADIX); 582 ptrdiff_t ndig = mpz_sizeinbase (*n, FLT_RADIX);
580 ptrdiff_t ddig = mpz_sizeinbase (*d, FLT_RADIX); 583 ptrdiff_t ddig = mpz_sizeinbase (*d, FLT_RADIX);
581 584
585 if (FASTER_TIMEFNS && ndig <= DBL_MANT_DIG && ddig <= DBL_MANT_DIG)
586 return mpz_get_d (*n) / mpz_get_d (*d);
587
582 /* Scale with SCALE when doing integer division. That is, compute 588 /* Scale with SCALE when doing integer division. That is, compute
583 (N * FLT_RADIX**SCALE) / D [or, if SCALE is negative, N / (D * 589 (N * FLT_RADIX**SCALE) / D [or, if SCALE is negative, N / (D *
584 FLT_RADIX**-SCALE)] as a bignum, convert the bignum to double, 590 FLT_RADIX**-SCALE)] as a bignum, convert the bignum to double,