diff options
| author | Paul Eggert | 2018-08-17 12:37:57 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-08-17 12:38:30 -0700 |
| commit | 33002872364c69e2e6004fb981a8c975c3b38413 (patch) | |
| tree | 4ca6644df8b2476d8013ad47eda1c13bfb0aeccc /src | |
| parent | 9189afc1a823703e1cef648538ac4b22182eb099 (diff) | |
| download | emacs-33002872364c69e2e6004fb981a8c975c3b38413.tar.gz emacs-33002872364c69e2e6004fb981a8c975c3b38413.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/floatfns.c | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/src/floatfns.c b/src/floatfns.c index bbf7df4db37..ea2eb1016b1 100644 --- a/src/floatfns.c +++ b/src/floatfns.c | |||
| @@ -266,30 +266,43 @@ DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0, | |||
| 266 | 266 | ||
| 267 | DEFUN ("abs", Fabs, Sabs, 1, 1, 0, | 267 | DEFUN ("abs", Fabs, Sabs, 1, 1, 0, |
| 268 | doc: /* Return the absolute value of ARG. */) | 268 | doc: /* Return the absolute value of ARG. */) |
| 269 | (register Lisp_Object arg) | 269 | (Lisp_Object arg) |
| 270 | { | 270 | { |
| 271 | CHECK_NUMBER (arg); | 271 | CHECK_NUMBER (arg); |
| 272 | 272 | ||
| 273 | if (BIGNUMP (arg)) | 273 | if (FIXNUMP (arg)) |
| 274 | { | 274 | { |
| 275 | mpz_t val; | 275 | if (XFIXNUM (arg) < 0) |
| 276 | mpz_init (val); | 276 | { |
| 277 | mpz_abs (val, XBIGNUM (arg)->value); | 277 | EMACS_INT absarg = -XFIXNUM (arg); |
| 278 | arg = make_number (val); | 278 | if (absarg <= MOST_POSITIVE_FIXNUM) |
| 279 | mpz_clear (val); | 279 | arg = make_fixnum (absarg); |
| 280 | else | ||
| 281 | { | ||
| 282 | mpz_t val; | ||
| 283 | mpz_init (val); | ||
| 284 | mpz_set_intmax (val, absarg); | ||
| 285 | arg = make_number (val); | ||
| 286 | mpz_clear (val); | ||
| 287 | } | ||
| 288 | } | ||
| 280 | } | 289 | } |
| 281 | else if (FIXNUMP (arg) && XFIXNUM (arg) == MOST_NEGATIVE_FIXNUM) | 290 | else if (FLOATP (arg)) |
| 282 | { | 291 | { |
| 283 | mpz_t val; | 292 | if (signbit (XFLOAT_DATA (arg))) |
| 284 | mpz_init (val); | 293 | arg = make_float (- XFLOAT_DATA (arg)); |
| 285 | mpz_set_intmax (val, - MOST_NEGATIVE_FIXNUM); | 294 | } |
| 286 | arg = make_number (val); | 295 | else |
| 287 | mpz_clear (val); | 296 | { |
| 297 | if (mpz_sgn (XBIGNUM (arg)->value) < 0) | ||
| 298 | { | ||
| 299 | mpz_t val; | ||
| 300 | mpz_init (val); | ||
| 301 | mpz_neg (val, XBIGNUM (arg)->value); | ||
| 302 | arg = make_number (val); | ||
| 303 | mpz_clear (val); | ||
| 304 | } | ||
| 288 | } | 305 | } |
| 289 | else if (FLOATP (arg)) | ||
| 290 | arg = make_float (fabs (XFLOAT_DATA (arg))); | ||
| 291 | else if (XFIXNUM (arg) < 0) | ||
| 292 | XSETINT (arg, - XFIXNUM (arg)); | ||
| 293 | 306 | ||
| 294 | return arg; | 307 | return arg; |
| 295 | } | 308 | } |