summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3experimental/l3benchmark
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-11-20 22:02:39 +0000
committerKarl Berry <karl@freefriends.org>2018-11-20 22:02:39 +0000
commitb6f9a8150be60baacc19b5035f1e344d14d1582c (patch)
tree02b435f7462e170e5f491c222bb7523c377a6629 /Master/texmf-dist/source/latex/l3experimental/l3benchmark
parent2b465ca87794c05f1793552a8608392027a2e100 (diff)
l3 (20nov18)
git-svn-id: svn://tug.org/texlive/trunk@49205 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental/l3benchmark')
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx421
1 files changed, 209 insertions, 212 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx
index 8f3fc919b17..cf8414f22fc 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2018-10-31}
+% \date{Released 2018-11-19}
%
% \maketitle
%
@@ -71,54 +71,32 @@
% \section{Benchmark}
%
% \begin{variable}{\g_benchmark_duration_target_fp}
-% This variable controls roughly for how long \cs{benchmark:n} will
-% repeat code to more accurately benchmark it. The actual duration of
-% one call to \cs{benchmark:n} typically lasts between half and twice
-% \cs{g_benchmark_duration_target_fp} seconds, unless of course
-% running the code only once already lasts longer than this.
+% This variable (default value: $1$) controls roughly for how long
+% \cs{benchmark:n} will repeat code to more accurately benchmark it.
+% The actual duration of one call to \cs{benchmark:n} typically lasts
+% between half and twice \cs{g_benchmark_duration_target_fp} seconds,
+% unless of course running the code only once already lasts longer
+% than this.
% \end{variable}
%
-% \begin{variable}{\g_benchmark_time_fp, \g_benchmark_ops_fp}
-% Functions such as \cs{benchmark:n} store the measured time in
-% \cs{g_benchmark_time_fp} (in seconds). Functions such as
-% \cs{benchmark_normalized:n} store the estimated number of operations
-% in \cs{g_benchmark_ops_fp}.
-% \end{variable}
-%
-% \begin{function}{\benchmark_display:, \benchmark_display_in_ops:}
-% \begin{syntax}
-% \cs{benchmark_display:}
-% \end{syntax}
-% Prints the time \cs{g_benchmark_time_fp} (in seconds) or the
-% estimated number of operations \cs{g_benchmark_ops_fp} to the
-% terminal. These functions are called by functions such as
-% \cs{benchmark:n} and can be redefined by the user.
-% \end{function}
-%
-% \begin{function}{\benchmark_once:n, \benchmark_once_in_ops:n, \benchmark_once_silent:n}
+% \begin{function}{\benchmark_once:n}
% \begin{syntax}
% \cs{benchmark_once:n} \Arg{code}
% \end{syntax}
-% Measures the time taken by \TeX{} to run the \meta{code} once, sets
-% \cs{g_benchmark_time_fp} and \cs{g_benchmark_ops_fp}, and calls
-% \cs{benchmark_display:}. The \meta{code} is run only once so the
-% time may be quite inaccurate for fast code. The
-% \cs{benchmark_once_silent:n} function omits the call to
-% \cs{benchmark_display:}, while \cs{benchmark_once_in_ops:n} calls
-% \cs{benchmark_display_in_ops:} instead.
+% Prints to the terminal the time taken by \TeX{} to run the
+% \meta{code}, and an estimated number of elementary operations. The
+% \meta{code} is run only once so the time may be quite inaccurate for
+% fast code.
% \end{function}
%
-% \begin{function}{\benchmark:n, \benchmark_in_ops:n, \benchmark_silent:n}
+% \begin{function}{\benchmark:n}
% \begin{syntax}
% \cs{benchmark:n} \Arg{code}
% \end{syntax}
-% Measures the time taken by \TeX{} to run the \meta{code}, sets
-% \cs{g_benchmark_time_fp} and \cs{g_benchmark_ops_fp}, and calls
-% \cs{benchmark_display:}. The \meta{code} may be run many times and
-% not within a group, thus code with side-effects may cause problems.
-% The \cs{benchmark_silent:n} function omits the call to
-% \cs{benchmark_display:}, while \cs{benchmark_in_ops:n} calls
-% \cs{benchmark_display_in_ops:} instead.
+% Prints to the terminal the time taken by \TeX{} to run the
+% \meta{code}, and an estimated number of elementary operations. The
+% \meta{code} may be run many times and not within a group, thus code
+% with side-effects may cause problems.
% \end{function}
%
% \begin{function}{\benchmark_tic:, \benchmark_toc:}
@@ -130,8 +108,8 @@
% tic/toc commands can be used instead to time between two points in
% the code. When executed, \cs{benchmark_tic:} will print a line to the
% terminal, and \cs{benchmark_toc:} will print a matching line with a
-% time to indicate the duration between them in seconds. Note that
-% these commands can be nested.
+% time to indicate the duration between them in seconds.
+% These commands can be nested.
% \end{function}
%
% \end{documentation}
@@ -148,7 +126,7 @@
%
% \begin{macrocode}
%<*package>
-\ProvidesExplPackage{l3benchmark}{2018-10-31}{}
+\ProvidesExplPackage{l3benchmark}{2018-11-19}{}
{L3 Experimental benchmarking}
%</package>
% \end{macrocode}
@@ -163,8 +141,7 @@
% \begin{macro}[EXP,pTF]{\sys_if_timer_exist:}
% In \LuaTeX{}, use emulation (see \pkg{l3luatex}),
% otherwise try to locate the primitive. The
-% elapsed time will be available if this succeeds or if unrestricted
-% shell escape is available.
+% elapsed time will be available if this succeeds.
% \begin{macrocode}
\sys_if_engine_luatex:TF
{
@@ -228,97 +205,35 @@
%<@@=benchmark>
% \end{macrocode}
%
-% \begin{variable}{\g_benchmark_time_fp, \g_benchmark_ops_fp}
-% Functions such as \cs{benchmark:n} store the measured time in
-% \cs{g_benchmark_time_fp} (in seconds) and the estimated number of
-% operations in \cs{g_benchmark_ops_fp}.
+% \begin{variable}{\g_benchmark_duration_target_fp}
+% The benchmark is constrained to take roughly (from half to twice)
+% \cs{g_benchmark_duration_target_fp} seconds, unless one iteration of
+% the code takes longer.
% \begin{macrocode}
-\fp_new:N \g_benchmark_time_fp
-\fp_new:N \g_benchmark_ops_fp
+\fp_new:N \g_benchmark_duration_target_fp
+\fp_gset:Nn \g_benchmark_duration_target_fp { 1 }
% \end{macrocode}
% \end{variable}
%
-% \begin{macro}{\benchmark_display:, \benchmark_display_in_ops:}
-% Function to display the time that was measured or the estimated
-% number of operations. This can be redefined by the user.
-% \begin{macrocode}
-\cs_new_protected:Npn \benchmark_display:
- { \iow_term:x { \fp_to_tl:N \g_benchmark_time_fp \c_space_tl seconds } }
-\cs_new_protected:Npn \benchmark_display_in_ops:
- {
- \iow_term:x
- {
- \fp_compare:nTF { \g_benchmark_ops_fp > 1e9 }
- { \fp_to_tl:n { \g_benchmark_ops_fp * 1e-9 } ~ G~ops }
- {
- \fp_compare:nTF { \g_benchmark_ops_fp > 1e6 }
- { \fp_to_tl:n { \g_benchmark_ops_fp * 1e-6 } ~ M~ops }
- {
- \fp_compare:nTF { \g_benchmark_ops_fp > 1e3 }
- { \fp_to_tl:n { \g_benchmark_ops_fp * 1e-3 } ~ K~ops }
- { \fp_to_tl:n { \g_benchmark_ops_fp } ~ ops }
- }
- }
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
+% Having access to the system time is essential.
% \begin{macrocode}
\sys_if_timer_exist:F
{
- \msg_new:nnnn { benchmark } { no-time }
- { The~l3benchmark~package~failed~to~access~a~clock. }
- { The~current~engine~provides~no~way~to~access~the~system~time. }
+ \fp_gset:Nn \g_benchmark_duration_target_fp { nan }
\cs_new_protected:Npn \benchmark_once:n #1
{ \msg_error:nn { benchmark } { no-time } }
- \cs_new_protected:Npn \benchmark_once_in_ops:n #1
- { \msg_error:nn { benchmark } { no-time } }
- \cs_new_protected:Npn \benchmark_once_silent:n #1
+ \cs_new_eq:NN \benchmark:n \benchmark_once:n
+ \cs_new_protected:Npn \benchmark_tic:
{ \msg_error:nn { benchmark } { no-time } }
- \cs_new_protected:Npn \benchmark:n #1
- { \msg_error:nn { benchmark } { no-time } }
- \cs_new_protected:Npn \benchmark_in_ops:n #1
- { \msg_error:nn { benchmark } { no-time } }
- \cs_new_protected:Npn \benchmark_silent:n #1
- { \msg_error:nn { benchmark } { no-time } }
- \fp_gset:Nn \g_benchmark_time_fp { nan }
- \fp_gset:Nn \g_benchmark_ops_fp { nan }
+ \cs_new_eq:NN \benchmark_toc: \benchmark_tic:
+ \msg_new:nnnn { benchmark } { no-time }
+ { The~l3benchmark~package~failed~to~access~a~clock. }
+ { The~current~engine~provides~no~way~to~access~the~system~time. }
\msg_critical:nn { benchmark } { no-time }
}
% \end{macrocode}
%
-% \begin{variable}{\g_benchmark_duration_target_fp, \g_@@_duration_int}
-% The benchmark is constrained to take roughly (from half to twice)
-% \cs{g_benchmark_duration_target_fp} seconds, more precisely
-% \cs{g_@@_duration_int} scaled seconds, unless one iteration of the
-% code takes longer.
-% \begin{macrocode}
-\fp_new:N \g_benchmark_duration_target_fp
-\fp_gset:Nn \g_benchmark_duration_target_fp { 1 }
-\int_new:N \g_@@_duration_int
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\g_@@_time_int, \g_@@_time_a_int, \g_@@_time_b_int, \g_@@_time_c_int, \g_@@_time_d_int}
-% These variables hold the time for running a piece of code, as an
-% integer in scaled seconds.
-% \begin{macrocode}
-\int_new:N \g_@@_time_int
-\int_new:N \g_@@_time_a_int
-\int_new:N \g_@@_time_b_int
-\int_new:N \g_@@_time_c_int
-\int_new:N \g_@@_time_d_int
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\g_@@_repeat_int}
-% Holds the number of times that the piece of code was
-% repeated when timing.
-% \begin{macrocode}
-\int_new:N \g_@@_repeat_int
-% \end{macrocode}
-% \end{variable}
+% \subsubsection{Raw measurement}
%
% \begin{variable}{\g_@@_nesting_int}
% \begin{macro}{\@@_raw:nN, \@@_raw_aux:N, \@@_raw_end:N}
@@ -401,74 +316,115 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\benchmark:n, \benchmark_silent:n}
-% The main timing function. First time the user code once. If that
-% took more than a third of a second we're done. If that took much
-% less than a second, quadruple the number of copies until it takes a
-% reasonable amount of time (this is to avoid division by a possibly
-% zero time). Once we reach a reasonable time, compute a number of
-% times that can fit in one quarter of a second and measure that four
-% times. To save time we reuse the result of the first pass if
-% \cs{g_@@_repeat_int} is one. Once we have four results, find the smallest,
-% divided by $65536$ and by the number of repetitions, and display that.
+% \subsubsection{Main benchmarking}
+%
+% \begin{variable}{\g_@@_time_fp, \g_@@_ops_fp}
+% Functions such as \cs{benchmark:n} store the measured time in
+% \cs{g_@@_time_fp} (in seconds) and the estimated number of
+% operations in \cs{g_@@_ops_fp}.
+% \begin{macrocode}
+\fp_new:N \g_@@_time_fp
+\fp_new:N \g_@@_ops_fp
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_duration_int}
+% A conversion of \cs{g_benchmark_duration_target_fp} seconds into scaled seconds.
+% \begin{macrocode}
+\int_new:N \g_@@_duration_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_time_int, \g_@@_time_a_int, \g_@@_time_b_int, \g_@@_time_c_int, \g_@@_time_d_int}
+% These variables hold the time for running a piece of code, as an
+% integer in scaled seconds.
+% \begin{macrocode}
+\int_new:N \g_@@_time_int
+\int_new:N \g_@@_time_a_int
+\int_new:N \g_@@_time_b_int
+\int_new:N \g_@@_time_c_int
+\int_new:N \g_@@_time_d_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_repeat_int}
+% Holds the number of times that the piece of code was
+% repeated when timing.
+% \begin{macrocode}
+\int_new:N \g_@@_repeat_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_code_tl}
+% Holds the piece of code to repeat.
% \begin{macrocode}
-\fp_new:N \g_@@_one_op_fp
\tl_new:N \g_@@_code_tl
-\cs_new_protected:Npn \benchmark:n #1
- { \benchmark_silent:n {#1} \benchmark_display: }
-\cs_new_protected:Npn \benchmark_in_ops:n #1
- { \benchmark_silent:n {#1} \benchmark_display_in_ops: }
-\cs_new_protected:Npn \@@_measure_op:
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\benchmark_once:n}
+% Convert the raw time from scaled seconds to seconds, and convert to
+% a number of operations. It is important to measure the elementary
+% operation before running the user code because both measurements use
+% the same temporary variables.
+% \begin{macrocode}
+\cs_new_protected:Npn \benchmark_once:n #1
{
- \int_gset:Nn \g_@@_duration_int { 256 }
- \tl_gset:Nn \g_@@_code_tl
- { \int_gset:Nn \g_@@_duration_int { 256 } } % arbitrary single operation
- \@@_aux:
- \fp_gset_eq:NN \g_@@_one_op_fp \g_benchmark_time_fp
- \fp_compare:nNnT \g_@@_one_op_fp < { 1e-6 }
- { \fp_gset:Nn \g_@@_one_op_fp { 1e-6 } }
+ \@@_measure_op:
+ \@@_raw:nN {#1} \g_@@_time_int
+ \fp_gset:Nn \g_@@_time_fp { \g_@@_time_int / 65536 }
+ \@@_display:
}
-\cs_new_protected:Npn \benchmark_silent:n #1
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\benchmark:n}
+% After setting up some variables the work is done by \cs{@@_aux:}.
+% \begin{macrocode}
+\cs_new_protected:Npn \benchmark:n #1
{
\@@_measure_op:
- \int_gset:Nn \g_@@_duration_int
- { \fp_to_int:n { 65536 * \g_benchmark_duration_target_fp } }
\tl_gset:Nn \g_@@_code_tl {#1}
\@@_aux:
- \fp_gset:Nn \g_benchmark_ops_fp
- { \g_benchmark_time_fp / \g_@@_one_op_fp }
+ \@@_display:
}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_aux:}
+% The main timing function. First time the user code once. If that
+% took more than half the allotted time (\cs{g_@@_duration_int}) we're
+% done. If that took much less, repeatedly quadruple the number of
+% copies until it takes a reasonable amount of time. Once we reach a
+% reasonable time (or we risk an overflow), compute a number of times
+% that can fit in one quarter of the allotted time and measure that
+% four times. To save time we reuse the result of the first pass if
+% \cs{g_@@_repeat_int} is one. Once we have four results, find the
+% smallest, divided by $65536$ and by the number of repetitions, and
+% display that.
+% \begin{macrocode}
\cs_new_protected:Npn \@@_aux:
{
\int_gset:Nn \g_@@_repeat_int { 1 }
\@@_raw:nN { \g_@@_code_tl } \g_@@_time_int
\int_compare:nNnF \g_@@_time_int < { \g_@@_duration_int / 2 }
+ { \prg_break: }
+ \bool_until_do:nn
{
- \int_gset_eq:NN \g_@@_time_a_int \g_@@_time_int
- \int_gset_eq:NN \g_@@_time_b_int \g_@@_time_int
- \int_gset_eq:NN \g_@@_time_c_int \g_@@_time_int
- \int_gset_eq:NN \g_@@_time_d_int \g_@@_time_int
- \prg_break:
+ \int_compare_p:nNn \g_@@_time_int > { \g_@@_duration_int / 32 }
+ || \int_compare_p:nNn \g_@@_repeat_int > { \c_max_int / 4 }
}
- \int_while_do:nNnn \g_@@_time_int < { \g_@@_duration_int / 100 }
{
- \int_compare:nNnT \g_@@_repeat_int > { \c_max_int / 4 }
- {
- \int_gzero:N \g_@@_time_a_int
- \int_gzero:N \g_@@_time_b_int
- \int_gzero:N \g_@@_time_c_int
- \int_gzero:N \g_@@_time_d_int
- \prg_break:
- }
\int_gset:Nn \g_@@_repeat_int { 4 * \g_@@_repeat_int }
\@@_run:N \g_@@_time_int
}
\int_gset:Nn \g_@@_repeat_int
{
- \int_max:nn { 1 }
+ \fp_to_int:n
{
- \g_@@_duration_int * \g_@@_repeat_int
- / ( \g_@@_time_int * 4 )
+ max ( 1 , min ( \c_max_int ,
+ \g_@@_duration_int * \g_@@_repeat_int /
+ \int_eval:n { 4 * \g_@@_time_int } ) )
}
}
\int_compare:nNnTF \g_@@_repeat_int = 1
@@ -477,67 +433,112 @@
\@@_run:N \g_@@_time_b_int
\@@_run:N \g_@@_time_c_int
\@@_run:N \g_@@_time_d_int
- \prg_break_point:
- \fp_gset:Nn \g_benchmark_time_fp
+ \int_gset:Nn \g_@@_time_int
{
\int_min:nn
{ \int_min:nn \g_@@_time_a_int \g_@@_time_b_int }
{ \int_min:nn \g_@@_time_c_int \g_@@_time_d_int }
- / \g_@@_repeat_int / 65536
}
+ \prg_break_point:
+ \int_compare:nNnT \g_@@_time_int < 3 { \int_gzero:N \g_@@_time_int }
+ \fp_gset:Nn \g_@@_time_fp
+ { \g_@@_time_int / \g_@@_repeat_int / 65536 }
}
\cs_new_protected:Npn \@@_run:N
{ \exp_args:NNo \@@_raw_replicate:nnN \g_@@_repeat_int { \g_@@_code_tl } }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\benchmark_once:n, \benchmark_once_in_ops:n, \benchmark_once_silent:n}
-% Convert from scaled seconds to seconds.
+% \subsubsection{Display}
+%
+% \begin{variable}{\g_@@_one_op_fp}
+% Time for one operation.
% \begin{macrocode}
-\cs_new_protected:Npn \benchmark_once:n #1
- { \benchmark_once_silent:n {#1} \benchmark_display: }
-\cs_new_protected:Npn \benchmark_once_in_ops:n #1
- { \benchmark_once_silent:n {#1} \benchmark_display_in_ops: }
-\cs_new_protected:Npn \benchmark_once_silent:n #1
+\fp_new:N \g_@@_one_op_fp
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_measure_op:}
+% Measure one arbitrary single operation (which we put in \cs{g_@@_code_tl}).
+% This uses a common auxiliary \cs{@@_aux:} with the main benchmark function.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_measure_op:
{
- \@@_measure_op:
- \@@_raw:nN {#1} \g_@@_time_int
- \fp_gset:Nn \g_benchmark_time_fp { \g_@@_time_int / 65536 }
- \fp_gset:Nn \g_benchmark_ops_fp
- { \g_benchmark_time_fp / \g_@@_one_op_fp }
+ \int_gset:Nn \g_@@_duration_int
+ { \fp_to_int:n { 65536 * \g_benchmark_duration_target_fp } / 4 }
+ \tl_gset:Nn \g_@@_code_tl
+ { \int_gadd:Nn \g_@@_duration_int { 0 } }
+ \@@_aux:
+ \fp_gset:Nn \g_@@_one_op_fp { max(\g_@@_time_fp, 1e-16) }
+ \int_gset:Nn \g_@@_duration_int
+ { \fp_to_int:n { 65536 * \g_benchmark_duration_target_fp } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_fp_to_tl:N, \@@_fp_to_tl_aux:nN}
+% Similar to \cs{fp_to_tl:N} but rounds to $3$ significant digits and
+% uses scientific notation starting from |1e3|.
+% \begin{macrocode}
+\cs_new:Npn \@@_fp_to_tl:N #1
+ {
+ \fp_compare:nTF { abs(#1) < 1000 }
+ { \fp_to_tl:n { round(#1, 2 - logb(#1)) } }
+ {
+ \exp_args:Nf \@@_fp_to_tl_aux:nN
+ { \fp_to_int:n { logb(#1) } } #1
+ }
+ }
+\cs_new:Npn \@@_fp_to_tl_aux:nN #1#2
+ { \fp_to_tl:n { round(#2 * 1e-#1, 2) } e#1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_display:}
+% Function to display the time that was measured and the estimated
+% number of operations.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_display:
+ {
+ \fp_gset:Nn \g_@@_ops_fp { \g_@@_time_fp / \g_@@_one_op_fp }
+ \iow_term:x
+ {
+ \@@_fp_to_tl:N \g_@@_time_fp \c_space_tl seconds \c_space_tl
+ ( \@@_fp_to_tl:N \g_@@_ops_fp \c_space_tl ops)
+ }
}
% \end{macrocode}
% \end{macro}
%
% \subsection{Benchmark tic toc}
%
-% \begin{variable}{\g_@@_tictoc_int, \g_@@_tictoc_seq}
+% \begin{variable}{\g_@@_tictoc_int, \g_@@_tictoc_seq, \l_@@_tictoc_pop_tl}
% \begin{macrocode}
\int_new:N \g_@@_tictoc_int
\seq_new:N \g_@@_tictoc_seq
+\tl_new:N \l_@@_tictoc_pop_tl
% \end{macrocode}
% \end{variable}
%
-% \begin{macro}{\benchmark_tic:, \@@_tic:}
+% \begin{macro}[EXP]{\@@_tictoc_prefix:}
+% We include the package name in analogy with continuation lines of
+% error/warning messages.
% \begin{macrocode}
-\cs_new_protected:Npn \benchmark_tic:
+\cs_new:Npn \@@_tictoc_prefix:
{
- \int_compare:nTF { \g_@@_tictoc_int == 0 }
- {
- \sys_gzero_timer:
- \@@_tic:
- }
- { \@@_tic: }
+ (l3benchmark) \c_space_tl
+ + \prg_replicate:nn { \g_@@_tictoc_int } { -+ } \c_space_tl
}
-\cs_new_protected:Npn \@@_tic:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\benchmark_tic:}
+% \begin{macrocode}
+\cs_new_protected:Npn \benchmark_tic:
{
- \exp_args:NNf \seq_put_right:Nn \g_@@_tictoc_seq { \sys_timer: }
+ \iow_term:x { \@@_tictoc_prefix: TIC }
+ \exp_args:NNf \seq_gput_right:Nn \g_@@_tictoc_seq { \sys_timer: }
\int_gincr:N \g_@@_tictoc_int
- \iow_term:x
- {
- \prg_replicate:nn {\g_@@_tictoc_int} {---+} \space
- TIC
- }
}
% \end{macrocode}
% \end{macro}
@@ -546,30 +547,26 @@
% \begin{macrocode}
\cs_new:Npn \benchmark_toc:
{
- \int_compare:nT { \g_@@_tictoc_int == 0 }
- { \msg_error:nn {benchmark} {toc-first} }
- \seq_pop_right:NN \g_@@_tictoc_seq \l_@@_tictoc_pop_tl
- \@@_toc:
+ \seq_gpop_right:NNTF \g_@@_tictoc_seq \l_@@_tictoc_pop_tl
+ { \@@_toc: }
+ { \msg_error:nn { benchmark } { toc-first } }
}
\cs_new_protected:Npn \@@_toc:
{
- \tl_set:Nx \l_@@_tictoc_tl
- {
- \fp_to_decimal:n
- { round( ( \sys_timer: - \l_@@_tictoc_pop_tl) / 65536 , 3 ) }
- }
+ \int_gdecr:N \g_@@_tictoc_int
+ \fp_gset:Nn \g_@@_time_fp
+ { ( \sys_timer: - \l_@@_tictoc_pop_tl ) / 65536 }
\iow_term:x
{
- \prg_replicate:nn {\g_@@_tictoc_int} {---+} \c_space_tl
+ \@@_tictoc_prefix:
TOC: \c_space_tl
- \l_@@_tictoc_tl \c_space_tl s
+ \@@_fp_to_tl:N \g_@@_time_fp \c_space_tl s
}
- \int_gdecr:N \g_@@_tictoc_int
}
-\msg_new:nnn {benchmark} {toc-first}
+\msg_new:nnn { benchmark } { toc-first }
{
- \token_to_str:N \benchmark_toc: \space without~
- \token_to_str:N \benchmark_tic: \space !
+ \token_to_str:N \benchmark_toc: \c_space_tl without~
+ \token_to_str:N \benchmark_tic: \c_space_tl !
}
% \end{macrocode}
% \end{macro}