aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2022-08-01 00:38:32 -0700
committerPaul Eggert2022-08-01 01:17:14 -0700
commit0a4477415c9df7d2cce8906155caadaa092b167e (patch)
treed4f92705bc07309b09e75ea631336bc76040855a
parent914cf4b91ba8bdf63cd10a66f970c396329beeab (diff)
downloademacs-0a4477415c9df7d2cce8906155caadaa092b167e.tar.gz
emacs-0a4477415c9df7d2cce8906155caadaa092b167e.zip
Improve float-time etc. performance
* src/timefns.c (decode_float_time): Assume T is finite. All callers changed. (decode_time_components): Assume FORM is not TIMEFORM_FLOAT. All callers changed. (decode_lisp_time): If the specified time is a float, signal an error if it is not finite. (Ffloat_time): If the specified time is a float, simply return it.
-rw-r--r--src/timefns.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/src/timefns.c b/src/timefns.c
index c8becac8634..078e1f40fb8 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -387,9 +387,9 @@ enum { flt_radix_power_size = DBL_MANT_DIG - DBL_MIN_EXP + 1 };
387 equals FLT_RADIX**P. */ 387 equals FLT_RADIX**P. */
388static Lisp_Object flt_radix_power; 388static Lisp_Object flt_radix_power;
389 389
390/* Convert T into an Emacs time *RESULT, truncating toward minus infinity. 390/* Convert the finite number T into an Emacs time *RESULT, truncating
391 Return zero if successful, an error number otherwise. */ 391 toward minus infinity. Signal an error if unsuccessful. */
392static int 392static void
393decode_float_time (double t, struct lisp_time *result) 393decode_float_time (double t, struct lisp_time *result)
394{ 394{
395 Lisp_Object ticks, hz; 395 Lisp_Object ticks, hz;
@@ -401,6 +401,7 @@ decode_float_time (double t, struct lisp_time *result)
401 else 401 else
402 { 402 {
403 int scale = double_integer_scale (t); 403 int scale = double_integer_scale (t);
404 eassume (scale < flt_radix_power_size);
404 405
405 if (scale < 0) 406 if (scale < 0)
406 { 407 {
@@ -412,8 +413,6 @@ decode_float_time (double t, struct lisp_time *result)
412 which is typically better than signaling overflow. */ 413 which is typically better than signaling overflow. */
413 scale = 0; 414 scale = 0;
414 } 415 }
415 else if (flt_radix_power_size <= scale)
416 return isnan (t) ? EDOM : EOVERFLOW;
417 416
418 /* Compute TICKS, HZ such that TICKS / HZ exactly equals T, where HZ is 417 /* Compute TICKS, HZ such that TICKS / HZ exactly equals T, where HZ is
419 T's frequency or 1, whichever is greater. Here, “frequency” means 418 T's frequency or 1, whichever is greater. Here, “frequency” means
@@ -431,7 +430,6 @@ decode_float_time (double t, struct lisp_time *result)
431 } 430 }
432 result->ticks = ticks; 431 result->ticks = ticks;
433 result->hz = hz; 432 result->hz = hz;
434 return 0;
435} 433}
436 434
437/* Make a 4-element timestamp (HI LO US PS) from TICKS and HZ. 435/* Make a 4-element timestamp (HI LO US PS) from TICKS and HZ.
@@ -705,7 +703,7 @@ enum timeform
705 TIMEFORM_TICKS_HZ /* fractional time: HI is ticks, LO is ticks per second */ 703 TIMEFORM_TICKS_HZ /* fractional time: HI is ticks, LO is ticks per second */
706 }; 704 };
707 705
708/* From the valid form FORM and the time components HIGH, LOW, USEC 706/* From the non-float form FORM and the time components HIGH, LOW, USEC
709 and PSEC, generate the corresponding time value. If LOW is 707 and PSEC, generate the corresponding time value. If LOW is
710 floating point, the other components should be zero and FORM should 708 floating point, the other components should be zero and FORM should
711 not be TIMEFORM_TICKS_HZ. 709 not be TIMEFORM_TICKS_HZ.
@@ -734,16 +732,7 @@ decode_time_components (enum timeform form,
734 return EINVAL; 732 return EINVAL;
735 733
736 case TIMEFORM_FLOAT: 734 case TIMEFORM_FLOAT:
737 { 735 eassume (false);
738 double t = XFLOAT_DATA (low);
739 if (result)
740 return decode_float_time (t, result);
741 else
742 {
743 *dresult = t;
744 return 0;
745 }
746 }
747 736
748 case TIMEFORM_NIL: 737 case TIMEFORM_NIL:
749 return decode_ticks_hz (timespec_ticks (current_timespec ()), 738 return decode_ticks_hz (timespec_ticks (current_timespec ()),
@@ -830,7 +819,16 @@ decode_lisp_time (Lisp_Object specified_time, bool decode_secs_only,
830 if (NILP (specified_time)) 819 if (NILP (specified_time))
831 form = TIMEFORM_NIL; 820 form = TIMEFORM_NIL;
832 else if (FLOATP (specified_time)) 821 else if (FLOATP (specified_time))
833 form = TIMEFORM_FLOAT; 822 {
823 double d = XFLOAT_DATA (specified_time);
824 if (!isfinite (d))
825 time_error (isnan (d) ? EDOM : EOVERFLOW);
826 if (result)
827 decode_float_time (d, result);
828 else
829 *dresult = d;
830 return TIMEFORM_FLOAT;
831 }
834 else if (CONSP (specified_time)) 832 else if (CONSP (specified_time))
835 { 833 {
836 high = XCAR (specified_time); 834 high = XCAR (specified_time);
@@ -878,7 +876,7 @@ decode_lisp_time (Lisp_Object specified_time, bool decode_secs_only,
878 return form; 876 return form;
879} 877}
880 878
881/* Convert a Lisp timestamp SPECIFIED_TIME to double. 879/* Convert a non-float Lisp timestamp SPECIFIED_TIME to double.
882 Signal an error if unsuccessful. */ 880 Signal an error if unsuccessful. */
883double 881double
884float_time (Lisp_Object specified_time) 882float_time (Lisp_Object specified_time)
@@ -1253,7 +1251,8 @@ If precise time stamps are required, use either `encode-time',
1253or (if you need time as a string) `format-time-string'. */) 1251or (if you need time as a string) `format-time-string'. */)
1254 (Lisp_Object specified_time) 1252 (Lisp_Object specified_time)
1255{ 1253{
1256 return make_float (float_time (specified_time)); 1254 return (FLOATP (specified_time) ? specified_time
1255 : make_float (float_time (specified_time)));
1257} 1256}
1258 1257
1259/* Write information into buffer S of size MAXSIZE, according to the 1258/* Write information into buffer S of size MAXSIZE, according to the