summaryrefslogtreecommitdiff
path: root/src/timefns.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2019-08-04 10:04:18 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2019-08-04 10:09:25 -0700
commit7748ef218cd7a9cffa984d165abe261cd60fae1a (patch)
treec5d26242ebbc69e808306743a875adc774a9cd73 /src/timefns.c
parent5f3f3884a0d2a88101d330b82ef5b584cfc02aa6 (diff)
downloademacs-7748ef218cd7a9cffa984d165abe261cd60fae1a.tar.gz
emacs-7748ef218cd7a9cffa984d165abe261cd60fae1a.tar.bz2
emacs-7748ef218cd7a9cffa984d165abe261cd60fae1a.zip
Tweak time arithmetic performance
* src/timefns.c (lispint_arith): New function, which should be a bit faster if B is 0, or if A is a bignum and B a fixnum with absolute value in unsigned long range. (time_arith): Use it.
Diffstat (limited to 'src/timefns.c')
-rw-r--r--src/timefns.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/src/timefns.c b/src/timefns.c
index cce9dd51ba9..ee43014979e 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -965,6 +965,37 @@ lisp_seconds_argument (Lisp_Object specified_time)
return t.tv_sec;
}
+/* Return the sum of the Lisp integers A and B.
+ Subtract instead of adding if SUBTRACT.
+ This function is tuned for small B. */
+static Lisp_Object
+lispint_arith (Lisp_Object a, Lisp_Object b, bool subtract)
+{
+ bool mpz_done = false;
+
+ if (FASTER_TIMEFNS && FIXNUMP (b))
+ {
+ if (EQ (b, make_fixnum (0)))
+ return a;
+ if (FIXNUMP (a))
+ return make_int (subtract
+ ? XFIXNUM (a) - XFIXNUM (b)
+ : XFIXNUM (a) + XFIXNUM (b));
+ if (eabs (XFIXNUM (b)) <= ULONG_MAX)
+ {
+ ((XFIXNUM (b) < 0) == subtract ? mpz_add_ui : mpz_sub_ui)
+ (mpz[0], XBIGNUM (a)->value, eabs (XFIXNUM (b)));
+ mpz_done = true;
+ }
+ }
+
+ if (!mpz_done)
+ (subtract ? mpz_sub : mpz_add) (mpz[0],
+ *bignum_integer (&mpz[0], a),
+ *bignum_integer (&mpz[1], b));
+ return make_integer_mpz ();
+}
+
/* Given Lisp operands A and B, add their values, and return the
result as a Lisp timestamp that is in (TICKS . HZ) form if either A
or B are in that form, (HI LO US PS) form otherwise. Subtract
@@ -989,18 +1020,7 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
if (FASTER_TIMEFNS && EQ (ta.hz, tb.hz))
{
hz = ta.hz;
- if (FIXNUMP (ta.ticks) && FIXNUMP (tb.ticks))
- ticks = make_int (subtract
- ? XFIXNUM (ta.ticks) - XFIXNUM (tb.ticks)
- : XFIXNUM (ta.ticks) + XFIXNUM (tb.ticks));
- else
- {
- (subtract ? mpz_sub : mpz_add)
- (mpz[0],
- *bignum_integer (&mpz[0], ta.ticks),
- *bignum_integer (&mpz[1], tb.ticks));
- ticks = make_integer_mpz ();
- }
+ ticks = lispint_arith (ta.ticks, tb.ticks, subtract);
}
else
{