]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve ‘abs’ performance
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 17 Aug 2018 19:37:57 +0000 (12:37 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 17 Aug 2018 19:38:30 +0000 (12:38 -0700)
* src/floatfns.c (Fabs): Improve performance by not copying
the argument if it would eql the result.  As a minor detail,
don't assume fixnums are two’s complement.

src/floatfns.c

index bbf7df4db37bc1fedf11436cc20316a9b2bf4bf5..ea2eb1016b1acb8f0de7fc02c76f4bdf70e2c9a9 100644 (file)
@@ -266,30 +266,43 @@ DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0,
 \f
 DEFUN ("abs", Fabs, Sabs, 1, 1, 0,
        doc: /* Return the absolute value of ARG.  */)
-  (register Lisp_Object arg)
+  (Lisp_Object arg)
 {
   CHECK_NUMBER (arg);
 
-  if (BIGNUMP (arg))
+  if (FIXNUMP (arg))
     {
-      mpz_t val;
-      mpz_init (val);
-      mpz_abs (val, XBIGNUM (arg)->value);
-      arg = make_number (val);
-      mpz_clear (val);
+      if (XFIXNUM (arg) < 0)
+       {
+         EMACS_INT absarg = -XFIXNUM (arg);
+         if (absarg <= MOST_POSITIVE_FIXNUM)
+           arg = make_fixnum (absarg);
+         else
+           {
+             mpz_t val;
+             mpz_init (val);
+             mpz_set_intmax (val, absarg);
+             arg = make_number (val);
+             mpz_clear (val);
+           }
+       }
     }
-  else if (FIXNUMP (arg) && XFIXNUM (arg) == MOST_NEGATIVE_FIXNUM)
+  else if (FLOATP (arg))
     {
-      mpz_t val;
-      mpz_init (val);
-      mpz_set_intmax (val, - MOST_NEGATIVE_FIXNUM);
-      arg = make_number (val);
-      mpz_clear (val);
+      if (signbit (XFLOAT_DATA (arg)))
+       arg = make_float (- XFLOAT_DATA (arg));
+    }
+  else
+    {
+      if (mpz_sgn (XBIGNUM (arg)->value) < 0)
+       {
+         mpz_t val;
+         mpz_init (val);
+         mpz_neg (val, XBIGNUM (arg)->value);
+         arg = make_number (val);
+         mpz_clear (val);
+       }
     }
-  else if (FLOATP (arg))
-    arg = make_float (fabs (XFLOAT_DATA (arg)));
-  else if (XFIXNUM (arg) < 0)
-    XSETINT (arg, - XFIXNUM (arg));
 
   return arg;
 }