diff options
| author | Paul Eggert | 2022-08-01 00:38:32 -0700 |
|---|---|---|
| committer | Paul Eggert | 2022-08-01 01:17:14 -0700 |
| commit | 0a4477415c9df7d2cce8906155caadaa092b167e (patch) | |
| tree | d4f92705bc07309b09e75ea631336bc76040855a /src | |
| parent | 914cf4b91ba8bdf63cd10a66f970c396329beeab (diff) | |
| download | emacs-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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/timefns.c | 39 |
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. */ |
| 388 | static Lisp_Object flt_radix_power; | 388 | static 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. */ |
| 392 | static int | 392 | static void |
| 393 | decode_float_time (double t, struct lisp_time *result) | 393 | decode_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. */ |
| 883 | double | 881 | double |
| 884 | float_time (Lisp_Object specified_time) | 882 | float_time (Lisp_Object specified_time) |
| @@ -1253,7 +1251,8 @@ If precise time stamps are required, use either `encode-time', | |||
| 1253 | or (if you need time as a string) `format-time-string'. */) | 1251 | or (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 |