]> git.eshelyaron.com Git - emacs.git/commitdiff
Time division speedups
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 3 Mar 2020 18:17:34 +0000 (10:17 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 3 Mar 2020 18:20:33 +0000 (10:20 -0800)
* 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.

src/timefns.c

index b96a6cb8875da74b857e13507ef8a3c58cc11129..0aa8775f9ff8cd211dda20401aa14353c7144152 100644 (file)
@@ -569,16 +569,22 @@ timespec_to_lisp (struct timespec t)
 static double
 frac_to_double (Lisp_Object numerator, Lisp_Object denominator)
 {
-  intmax_t intmax_numerator;
-  if (FASTER_TIMEFNS && EQ (denominator, make_fixnum (1))
-      && integer_to_intmax (numerator, &intmax_numerator))
-    return intmax_numerator;
+  intmax_t intmax_numerator, intmax_denominator;
+  if (FASTER_TIMEFNS
+      && integer_to_intmax (numerator, &intmax_numerator)
+      && integer_to_intmax (denominator, &intmax_denominator)
+      && ! INT_DIVIDE_OVERFLOW (intmax_numerator, intmax_denominator)
+      && intmax_numerator % intmax_denominator == 0)
+    return intmax_numerator / intmax_denominator;
 
   mpz_t const *n = bignum_integer (&mpz[0], numerator);
   mpz_t const *d = bignum_integer (&mpz[1], denominator);
   ptrdiff_t ndig = mpz_sizeinbase (*n, FLT_RADIX);
   ptrdiff_t ddig = mpz_sizeinbase (*d, FLT_RADIX);
 
+  if (FASTER_TIMEFNS && ndig <= DBL_MANT_DIG && ddig <= DBL_MANT_DIG)
+    return mpz_get_d (*n) / mpz_get_d (*d);
+
   /* Scale with SCALE when doing integer division.  That is, compute
      (N * FLT_RADIX**SCALE) / D [or, if SCALE is negative, N / (D *
      FLT_RADIX**-SCALE)] as a bignum, convert the bignum to double,