[latex3-commits] [git/LaTeX3-latex3-latex3] master: Add \benchmark_in_ops:n, \benchmark_once_in_ops:n (2ad7768)

Bruno Le Floch bruno at le-floch.fr
Wed May 9 01:12:02 CEST 2018


Repository : https://github.com/latex3/latex3
On branch  : master
Link       : https://github.com/latex3/latex3/commit/2ad7768098037a479d0a4ca371420d50e1f30c5c

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

commit 2ad7768098037a479d0a4ca371420d50e1f30c5c
Author: Bruno Le Floch <bruno at le-floch.fr>
Date:   Tue May 8 19:12:02 2018 -0400

    Add \benchmark_in_ops:n, \benchmark_once_in_ops:n
    
    These functions estimate the number of operations (typically \int_set:Nn
    or similar) used by the code.  It's just a rescaling of the time by a
    factor that depends on the computer, and that is measured just before
    running the other code.


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

2ad7768098037a479d0a4ca371420d50e1f30c5c
 l3trial/l3benchmark/l3benchmark.dtx |  127 +++++++++++++++++++++++++----------
 1 file changed, 90 insertions(+), 37 deletions(-)

diff --git a/l3trial/l3benchmark/l3benchmark.dtx b/l3trial/l3benchmark/l3benchmark.dtx
index 4c68c3b..0cd2806 100644
--- a/l3trial/l3benchmark/l3benchmark.dtx
+++ b/l3trial/l3benchmark/l3benchmark.dtx
@@ -94,41 +94,47 @@
 %   running the code only once already lasts longer than this.
 % \end{variable}
 %
-% \begin{variable}{\g_benchmark_time_fp}
+% \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).
+%   \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:}
+% \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) to the
-%   terminal.  This function is called by functions such as
+%   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_silent:n}
+% \begin{function}{\benchmark_once:n, \benchmark_once_in_ops:n, \benchmark_once_silent:n}
 %   \begin{syntax}
 %     \cs{benchmark_once:n} \Arg{code}
 %   \end{syntax}
-%   Sets \cs{g_benchmark_time_fp} to the time taken by \TeX{} to run the
-%   \meta{code} once, and calls \cs{benchmark_display:}.  The 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:}.
+%   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.
 % \end{function}
 %
-% \begin{function}{\benchmark:n, \benchmark_silent:n}
+% \begin{function}{\benchmark:n, \benchmark_in_ops:n, \benchmark_silent:n}
 %   \begin{syntax}
 %     \cs{benchmark:n} \Arg{code}
 %   \end{syntax}
-%   Sets \cs{g_benchmark_time_fp} to the time taken by \TeX{} to run the
-%   \meta{code}, and calls \cs{benchmark_display:}.  This function
-%   cannot be nested.  The \meta{code} may be run many times in a row,
-%   and not within a group, thus it should not have side-effects.  The
-%   \cs{benchmark_silent:n} function omits the call to
-%   \cs{benchmark_display:}.
+%   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.
 % \end{function}
 %
 % \begin{function}{\benchmark_tic:, \benchmark_toc:}
@@ -322,20 +328,39 @@ end
 %<@@=benchmark>
 %    \end{macrocode}
 %
-% \begin{variable}{\g_benchmark_time_fp}
+% \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).
+%   \cs{g_benchmark_time_fp} (in seconds) and the estimated number of
+%   operations in \cs{g_benchmark_ops_fp}.
 %    \begin{macrocode}
 \fp_new:N \g_benchmark_time_fp
+\fp_new:N \g_benchmark_ops_fp
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{macro}{\benchmark_display:}
-%   Function to display the time that was measured.  This can be
-%   redefined by the user.
+% \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 ~ 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}
 %
@@ -352,13 +377,18 @@ end
       }
     \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
       { \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 }
     \msg_critical:nn { benchmark } { no-time }
   }
 %    \end{macrocode}
@@ -432,19 +462,6 @@ end
 % \end{macro}
 % \end{variable}
 %
-% \begin{macro}{\benchmark_once:n, \benchmark_once_silent:n}
-%   Convert from scaled seconds to seconds.
-%    \begin{macrocode}
-\cs_new_protected:Npn \benchmark_once:n #1
-  { \benchmark_once_silent:n {#1} \benchmark_display: }
-\cs_new_protected:Npn \benchmark_once_silent:n #1
-  {
-    \@@_raw:nN {#1} \g_@@_time_int
-    \fp_gset:Nn \g_benchmark_time_fp { \g_@@_time_int / 65536 }
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_raw_replicate:nnN, \@@_tmp:w}
 %   Here, we wish to measure the time it takes for the piece of code
 %   |#2| to be run |#1| times, and store the result in the
@@ -521,15 +538,33 @@ end
 %   median and display that, divided by $65536$ and by the number of
 %   repetitions.
 %    \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:
+  {
+    \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
+  }
 \cs_new_protected:Npn \benchmark_silent:n #1
   {
+    \@@_measure_op:
     \int_gset:Nn \g_@@_duration_int
       { \fp_to_int:n { 65536 * \g_benchmark_duration_target_fp } }
-    \int_gset:Nn \g_@@_repeat_int { 1 }
     \tl_gset:Nn \g_@@_code_tl {#1}
+    \@@_aux:
+    \fp_gset:Nn \g_benchmark_ops_fp
+      { \g_benchmark_time_fp / \g_@@_one_op_fp }
+  }
+\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: }
@@ -567,6 +602,24 @@ end
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\benchmark_once:n, \benchmark_once_in_ops:n, \benchmark_once_silent:n}
+%   Convert from scaled seconds to seconds.
+%    \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
+  {
+    \@@_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 }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \subsection{Benchmark tic toc}
 %
 % \begin{variable}{\g_@@_tictoc_int, \g_@@_tictoc_seq}





More information about the latex3-commits mailing list