emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 3300287: Improve ‘abs’ performance


From: Paul Eggert
Subject: [Emacs-diffs] master 3300287: Improve ‘abs’ performance
Date: Fri, 17 Aug 2018 15:38:36 -0400 (EDT)

branch: master
commit 33002872364c69e2e6004fb981a8c975c3b38413
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Improve ‘abs’ performance
    
    * 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 | 47 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/src/floatfns.c b/src/floatfns.c
index bbf7df4..ea2eb10 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -266,30 +266,43 @@ DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0,
 
 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;
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]