[latex3-commits] [git/LaTeX3-latex3-latex3] master: Remove many user functions in l3benchmark, fix bugs for short benchmarks (04a6bdd)

Bruno Le Floch bruno at le-floch.fr
Sun Nov 4 01:59:55 CET 2018


Repository : https://github.com/latex3/latex3
On branch  : master
Link       : https://github.com/latex3/latex3/commit/04a6bddc6b6a21986259f430c33f38f024e05a06

>---------------------------------------------------------------

commit 04a6bddc6b6a21986259f430c33f38f024e05a06
Author: Bruno Le Floch <bruno at le-floch.fr>
Date:   Sat Nov 3 23:10:00 2018 +0100

    Remove many user functions in l3benchmark, fix bugs for short benchmarks
    
    This fixes overflows when code to be benchmarked took very short amounts
    of time, and this should also avoid getting the number of operations to
    be infinite.


>---------------------------------------------------------------

04a6bddc6b6a21986259f430c33f38f024e05a06
 l3experimental/l3benchmark/l3benchmark.dtx         |  374 ++++++++++----------
 .../l3benchmark/testfiles/m3benchmark000.tlg       |    2 +-
 .../l3benchmark/testfiles/m3benchmark001.lvt       |   27 +-
 .../l3benchmark/testfiles/m3benchmark001.tlg       |    2 +-
 .../l3benchmark/testfiles/m3benchmark001.xetex.tlg |   12 -
 5 files changed, 201 insertions(+), 216 deletions(-)

diff --git a/l3experimental/l3benchmark/l3benchmark.dtx b/l3experimental/l3benchmark/l3benchmark.dtx
index c29825b..805eea9 100644
--- a/l3experimental/l3benchmark/l3benchmark.dtx
+++ b/l3experimental/l3benchmark/l3benchmark.dtx
@@ -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:}
@@ -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,103 +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:
-  {
-    \fp_gset:Nn \g_benchmark_time_fp
-      { round(\g_benchmark_time_fp, 2 - logb(\g_benchmark_time_fp)) }
-    \iow_term:x { \fp_to_tl:N \g_benchmark_time_fp \c_space_tl seconds }
-  }
-\cs_new_protected:Npn \benchmark_display_in_ops:
-  {
-    \fp_gset:Nn \g_benchmark_ops_fp
-      { round(\g_benchmark_ops_fp, 2 - logb(\g_benchmark_ops_fp)) }
-    \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
-      { \msg_error:nn { benchmark } { no-time } }
-    \cs_new_protected:Npn \benchmark: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_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}
@@ -407,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
@@ -483,34 +433,79 @@
     \@@_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}
@@ -559,23 +554,20 @@
   }
 \cs_new_protected:Npn \@@_toc:
   {
-    \tl_set:Nx \l_@@_tictoc_tl
-      {
-        \fp_to_decimal:n
-          { round( ( \sys_timer: - \l_@@_tictoc_pop_tl) / 65536 , 3 ) }
-      }
+    \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
         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}
   {
-    \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}
diff --git a/l3experimental/l3benchmark/testfiles/m3benchmark000.tlg b/l3experimental/l3benchmark/testfiles/m3benchmark000.tlg
index c561501..455bf9d 100644
--- a/l3experimental/l3benchmark/testfiles/m3benchmark000.tlg
+++ b/l3experimental/l3benchmark/testfiles/m3benchmark000.tlg
@@ -2,6 +2,7 @@ This is a generated file for the LaTeX (2e + expl3) validation system.
 Don't change this file in any respect.
 (l3benchmark.sty
 Package: l3benchmark ....-..-.. L3 Experimental benchmarking
+\g__benchmark_nesting_int=\count...
 \g__benchmark_duration_int=\count...
 \g__benchmark_time_int=\count...
 \g__benchmark_time_a_int=\count...
@@ -9,6 +10,5 @@ Package: l3benchmark ....-..-.. L3 Experimental benchmarking
 \g__benchmark_time_c_int=\count...
 \g__benchmark_time_d_int=\count...
 \g__benchmark_repeat_int=\count...
-\g__benchmark_nesting_int=\count...
 \g__benchmark_tictoc_int=\count...
 )
diff --git a/l3experimental/l3benchmark/testfiles/m3benchmark001.lvt b/l3experimental/l3benchmark/testfiles/m3benchmark001.lvt
index 2d0e013..a73d480 100644
--- a/l3experimental/l3benchmark/testfiles/m3benchmark001.lvt
+++ b/l3experimental/l3benchmark/testfiles/m3benchmark001.lvt
@@ -17,9 +17,7 @@
 \sys_if_timer_exist:F
   {
     \benchmark_once:n \ERROR \TRUE
-    \benchmark_once_silent:n \ERROR \TRUE
     \benchmark:n \ERROR \TRUE
-    \benchmark_silent:n \ERROR \TRUE
     \END
   }
 
@@ -30,16 +28,23 @@
   { \prg_replicate:nn { 123 } { a , } }
 \cs_new_protected:Npn \test_slow_code:
   { \seq_reverse:N \l_tmpa_seq }
+\cs_new_protected:Npn \test_disable_iow:n #1
+  {
+    \group_begin:
+      \cs_set_eq:NN \iow_term:x \use_none:n
+      #1
+    \group_end:
+  }
 \TIMO
 
 \TEST { benchmark_once }
   {
-    \int_zero:N \l_tmpa_int
-    \benchmark_once_silent:n { \int_incr:N \l_tmpa_int }
-    \int_log:N \l_tmpa_int    % Check the code was done only once
-    \fp_compare:nTF { \g_benchmark_time_fp < 5e-5 }  % Check it took 0 to 3 scaled seconds
+    \int_gzero:N \g_tmpa_int
+    \test_disable_iow:n { \benchmark_once:n { \int_gincr:N \g_tmpa_int } }
+    \int_log:N \g_tmpa_int    % Check the code was done only once
+    \fp_compare:nTF { \g__benchmark_time_fp < 5e-5 }  % Check it took 0 to 3 scaled seconds
       { \TRUE }
-      { \ERROR \fp_show:N \g_benchmark_time_fp }
+      { \ERROR \fp_show:N \g__benchmark_time_fp }
   }
 
 \TEST { benchmark }
@@ -48,10 +53,10 @@
     \clist_clear:N \l_tmpb_clist
     \prg_replicate:nn { 3 }
       {
-        \benchmark_silent:n { \test_slow_code: }
-        \clist_put_right:Nx \l_tmpa_clist { \fp_to_tl:N \g_benchmark_time_fp }
-        \benchmark_silent:n { \test_slow_code: \test_slow_code: }
-        \clist_put_right:Nx \l_tmpb_clist { \fp_to_tl:N \g_benchmark_time_fp }
+        \test_disable_iow:n { \benchmark:n { \test_slow_code: } }
+        \clist_put_right:Nx \l_tmpa_clist { \fp_to_tl:N \g__benchmark_time_fp }
+        \test_disable_iow:n { \benchmark:n { \test_slow_code: \test_slow_code: } }
+        \clist_put_right:Nx \l_tmpb_clist { \fp_to_tl:N \g__benchmark_time_fp }
       }
     \fp_compare:nTF % Check that doing code twice takes between 1.5 and 2.5 times as much
       {
diff --git a/l3experimental/l3benchmark/testfiles/m3benchmark001.tlg b/l3experimental/l3benchmark/testfiles/m3benchmark001.tlg
index 1904c90..78338f6 100644
--- a/l3experimental/l3benchmark/testfiles/m3benchmark001.tlg
+++ b/l3experimental/l3benchmark/testfiles/m3benchmark001.tlg
@@ -5,7 +5,7 @@ TEST 1: benchmark_once
 ============================================================
 Defining \g__benchmark_1_int on line ...
 \g__benchmark_1_int=\count...
-> \l_tmpa_int=1.
+> \g_tmpa_int=1.
 TRUE
 ============================================================
 ============================================================
diff --git a/l3experimental/l3benchmark/testfiles/m3benchmark001.xetex.tlg b/l3experimental/l3benchmark/testfiles/m3benchmark001.xetex.tlg
index bd5f01b..58c1f9c 100644
--- a/l3experimental/l3benchmark/testfiles/m3benchmark001.xetex.tlg
+++ b/l3experimental/l3benchmark/testfiles/m3benchmark001.xetex.tlg
@@ -12,15 +12,3 @@ For immediate help type H <return>.
 l. ...  }
 The current engine provides no way to access the system time.
 TRUE
-! Package benchmark Error: The l3benchmark package failed to access a clock.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The current engine provides no way to access the system time.
-TRUE
-! Package benchmark Error: The l3benchmark package failed to access a clock.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-The current engine provides no way to access the system time.
-TRUE





More information about the latex3-commits mailing list