[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