[latex3-commits] [git/LaTeX3-latex3-latex3] main: Optimize \tl_set_eq:NN and elementary register operations (fixes #932) (9137c5640)

Bruno Le Floch blflatex at gmail.com
Sat May 22 00:59:16 CEST 2021


Repository : https://github.com/latex3/latex3
On branch  : main
Link       : https://github.com/latex3/latex3/commit/9137c564071ba57cc80ca633877c8bc5021852ed

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

commit 9137c564071ba57cc80ca633877c8bc5021852ed
Author: Bruno Le Floch <blflatex at gmail.com>
Date:   Sat May 22 00:59:16 2021 +0200

    Optimize \tl_set_eq:NN and elementary register operations (fixes #932)


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

9137c564071ba57cc80ca633877c8bc5021852ed
 l3kernel/CHANGELOG.md |  2 ++
 l3kernel/l3debug.dtx  |  4 +++
 l3kernel/l3int.dtx    | 36 +++++++++++-----------
 l3kernel/l3skip.dtx   | 82 ++++++++++++++++++++++++---------------------------
 l3kernel/l3tl.dtx     | 24 +++++++--------
 5 files changed, 75 insertions(+), 73 deletions(-)

diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md
index d7727502a..4f6e7faf1 100644
--- a/l3kernel/CHANGELOG.md
+++ b/l3kernel/CHANGELOG.md
@@ -24,6 +24,8 @@ this project uses date-based 'snapshot' version identifiers.
 - Removing duplicates in clists when items contain commas (issue #917)
 
 ### Changed
+- Slight speed up in some elementary int/dim/skip/muskip operations and
+  in setting tl or clist variables equal.
 - Speed up mapping functions in l3clist, l3prop, l3seq, l3tl
 
 ## [2021-05-11]
diff --git a/l3kernel/l3debug.dtx b/l3kernel/l3debug.dtx
index 319fa7aa2..48d659026 100644
--- a/l3kernel/l3debug.dtx
+++ b/l3kernel/l3debug.dtx
@@ -807,6 +807,7 @@
       \box_set_eq:NN
       \box_set_eq_drop:NN
       \box_set_to_last:N
+      \clist_clear:N
       \clist_set_eq:NN
       \dim_zero:N
       \dim_set:Nn
@@ -837,6 +838,7 @@
       \skip_add:Nn
       \skip_sub:Nn
       \__kernel_tl_set:Nx
+      \tl_clear:N
       \tl_set_eq:NN
       \tl_put_left:Nn
       \tl_put_left:NV
@@ -869,6 +871,7 @@
       \box_gset_eq_drop:NN
       \box_gset_to_last:N
       \cctab_gset:Nn
+      \clist_gclear:N
       \clist_gset_eq:NN
       \dim_gset_eq:NN
       \dim_gzero:N
@@ -899,6 +902,7 @@
       \skip_gadd:Nn
       \skip_gsub:Nn
       \__kernel_tl_gset:Nx
+      \tl_gclear:N
       \tl_gset_eq:NN
       \tl_gput_left:Nn
       \tl_gput_left:NV
diff --git a/l3kernel/l3int.dtx b/l3kernel/l3int.dtx
index 5994a193c..086cfa382 100644
--- a/l3kernel/l3int.dtx
+++ b/l3kernel/l3int.dtx
@@ -1088,13 +1088,14 @@
 %
 % \begin{macro}{\int_eval:n}
 % \begin{macro}{\int_eval:w}
-%   Wrapper for \cs{@@_eval:w}: can be used in an integer expression
-%   or directly in the input stream.
-%   When debugging, use parentheses to catch early termination.
+%   Wrapper for \cs{@@_eval:w}: can be used in an integer expression or
+%   directly in the input stream.  It is very slightly faster to use
+%   \tn{the} rather than \tn{number} to turn the expression to a number.
+%   When debugging, we introduce parentheses to catch early termination (see \pkg{l3debug}).
 %    \begin{macrocode}
 \cs_new:Npn \int_eval:n #1
-  { \int_value:w \@@_eval:w #1 \@@_eval_end: }
-\cs_new:Npn \int_eval:w { \int_value:w \@@_eval:w }
+  { \tex_the:D \@@_eval:w #1 \@@_eval_end: }
+\cs_new:Npn \int_eval:w { \tex_the:D \@@_eval:w }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -1399,15 +1400,17 @@
 % \begin{macro}{\int_gsub:Nn, \int_gsub:cn}
 % \UnitTested
 %    Adding and subtracting to and from a counter.
+%    Including here the optional |by| would slow down these operations
+%    by a few percent.
 %    \begin{macrocode}
 \cs_new_protected:Npn \int_add:Nn #1#2
-  { \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: }
+  { \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: }
 \cs_new_protected:Npn \int_sub:Nn #1#2
-  { \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: }
+  { \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: }
 \cs_new_protected:Npn \int_gadd:Nn #1#2
-  { \tex_global:D \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: }
+  { \tex_global:D \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: }
 \cs_new_protected:Npn \int_gsub:Nn #1#2
-  { \tex_global:D \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: }
+  { \tex_global:D \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: }
 \cs_generate_variant:Nn \int_add:Nn  { c }
 \cs_generate_variant:Nn \int_gadd:Nn { c }
 \cs_generate_variant:Nn \int_sub:Nn  { c }
@@ -1452,12 +1455,14 @@
 % \begin{macro}{\int_gset:Nn, \int_gset:cn}
 % \UnitTested
 %   As integers are register-based \TeX{} issues an error
-%   if they are not defined.
+%   if they are not defined.  While the |=| sign is optional, this
+%   version with |=| is slightly quicker than without, while adding the
+%   optional space after |=| slows things down minutely.
 %    \begin{macrocode}
 \cs_new_protected:Npn \int_set:Nn #1#2
-  { #1 ~ \@@_eval:w #2 \@@_eval_end: }
+  { #1 = \@@_eval:w #2 \@@_eval_end: }
 \cs_new_protected:Npn \int_gset:Nn #1#2
-  { \tex_global:D #1 ~ \@@_eval:w #2 \@@_eval_end: }
+  { \tex_global:D #1 = \@@_eval:w #2 \@@_eval_end: }
 \cs_generate_variant:Nn \int_set:Nn  { c }
 \cs_generate_variant:Nn \int_gset:Nn { c }
 %    \end{macrocode}
@@ -1468,13 +1473,10 @@
 %
 % \begin{macro}{\int_use:N, \int_use:c}
 % \UnitTested
-%    Here is how counters are accessed:
+%    Here is how counters are accessed.
+%    We hand-code the |c| variant for some speed gain.
 %    \begin{macrocode}
 \cs_new_eq:NN \int_use:N \tex_the:D
-%    \end{macrocode}
-%    We hand-code this for some speed gain:
-%    \begin{macrocode}
-%\cs_generate_variant:Nn \int_use:N { c }
 \cs_new:Npn \int_use:c #1 { \tex_the:D \cs:w #1 \cs_end: }
 %    \end{macrocode}
 % \end{macro}
diff --git a/l3kernel/l3skip.dtx b/l3kernel/l3skip.dtx
index fa2b011f9..06b2e2468 100644
--- a/l3kernel/l3skip.dtx
+++ b/l3kernel/l3skip.dtx
@@ -1129,7 +1129,7 @@
 \cs_new_protected:Npn \dim_const:Nn #1#2
   {
     \dim_new:N #1
-    \tex_global:D #1 ~ \dim_eval:n {#2} \scan_stop:
+    \tex_global:D #1 = \dim_eval:n {#2} \scan_stop:
   }
 \cs_generate_variant:Nn \dim_const:Nn { c }
 %    \end{macrocode}
@@ -1139,11 +1139,12 @@
 % \begin{macro}{\dim_gzero:N, \dim_gzero:c}
 %   Reset the register to zero.  Using \cs{c_zero_skip} deals with the
 %   case where the variable passed is incorrectly a skip (for example a
-%   \LaTeXe{} length).
+%   \LaTeXe{} length).  Besides, these functions are then simply copied
+%   for \cs{skip_zero:N} and related functions.
 %    \begin{macrocode}
-\cs_new_protected:Npn \dim_zero:N #1 { #1 \c_zero_skip }
+\cs_new_protected:Npn \dim_zero:N #1 { #1 = \c_zero_skip }
 \cs_new_protected:Npn \dim_gzero:N #1
-  { \tex_global:D #1 \c_zero_skip }
+  { \tex_global:D #1 = \c_zero_skip }
 \cs_generate_variant:Nn \dim_zero:N  { c }
 \cs_generate_variant:Nn \dim_gzero:N { c }
 %    \end{macrocode}
@@ -1184,9 +1185,9 @@
 %   length).
 %    \begin{macrocode}
 \cs_new_protected:Npn \dim_set:Nn #1#2
-  { #1 ~ \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+  { #1 = \@@_eval:w #2 \@@_eval_end: \scan_stop: }
 \cs_new_protected:Npn \dim_gset:Nn #1#2
-  { \tex_global:D #1 ~ \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+  { \tex_global:D #1 = \@@_eval:w #2 \@@_eval_end: \scan_stop: }
 \cs_generate_variant:Nn \dim_set:Nn  { c }
 \cs_generate_variant:Nn \dim_gset:Nn { c }
 %    \end{macrocode}
@@ -1213,27 +1214,27 @@
 % \begin{macro}{\dim_gadd:Nn, \dim_gadd:cn}
 % \begin{macro}{\dim_sub:Nn, \dim_sub:cn}
 % \begin{macro}{\dim_gsub:Nn, \dim_gsub:cn}
-%   Using |by| here deals with the (incorrect) case |\dimen123|.
+%   Using |by| here would slow things down just to detect nonsensical
+%   cases such as passing |\dimen 123| as the first argument.
 %   Using \cs{scan_stop:} deals with skip variables.  Since
 %   debugging checks that the variable is correctly local/global, the
 %   global versions cannot be defined as \cs{tex_global:D} followed by
-%   the local versions.  The debugging code is inserted by
-%   \cs{@@_tmp:w}.
+%   the local versions.
 %    \begin{macrocode}
 \cs_new_protected:Npn \dim_add:Nn #1#2
-  { \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+  { \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: \scan_stop: }
 \cs_new_protected:Npn \dim_gadd:Nn #1#2
   {
-    \tex_global:D \tex_advance:D #1 by
+    \tex_global:D \tex_advance:D #1
       \@@_eval:w #2 \@@_eval_end: \scan_stop:
   }
 \cs_generate_variant:Nn \dim_add:Nn  { c }
 \cs_generate_variant:Nn \dim_gadd:Nn { c }
 \cs_new_protected:Npn \dim_sub:Nn #1#2
-  { \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+  { \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: \scan_stop: }
 \cs_new_protected:Npn \dim_gsub:Nn #1#2
   {
-    \tex_global:D \tex_advance:D #1 by
+    \tex_global:D \tex_advance:D #1
       -\@@_eval:w #2 \@@_eval_end: \scan_stop:
   }
 \cs_generate_variant:Nn \dim_sub:Nn  { c }
@@ -1642,13 +1643,9 @@
 % \end{macro}
 %
 % \begin{macro}{\dim_use:N, \dim_use:c}
-%   Accessing a \meta{dim}.
+%   Accessing a \meta{dim}.  We hand-code the |c| variant for some speed gain.
 %    \begin{macrocode}
 \cs_new_eq:NN \dim_use:N \tex_the:D
-%    \end{macrocode}
-%    We hand-code this for some speed gain:
-%    \begin{macrocode}
-%\cs_generate_variant:Nn \dim_use:N { c }
 \cs_new:Npn \dim_use:c #1 { \tex_the:D \cs:w #1 \cs_end: }
 %    \end{macrocode}
 % \end{macro}
@@ -1673,7 +1670,7 @@
       ##1 . ##2 \tl_to_str:n { pt }
   }
       {
-        \int_compare:nNnTF {#2} > { 0 }
+        \int_compare:nNnTF {#2} > \c_zero_int
           { #1 . #2 }
           { #1 }
       }
@@ -1808,7 +1805,7 @@
 \cs_new_protected:Npn \skip_const:Nn #1#2
   {
     \skip_new:N #1
-    \tex_global:D #1 ~ \skip_eval:n {#2} \scan_stop:
+    \tex_global:D #1 = \skip_eval:n {#2} \scan_stop:
   }
 \cs_generate_variant:Nn \skip_const:Nn { c }
 %    \end{macrocode}
@@ -1818,8 +1815,8 @@
 % \begin{macro}{\skip_gzero:N, \skip_gzero:c}
 %   Reset the register to zero.
 %    \begin{macrocode}
-\cs_new_protected:Npn \skip_zero:N #1 { #1 \c_zero_skip }
-\cs_new_protected:Npn \skip_gzero:N #1 { \tex_global:D #1 \c_zero_skip }
+\cs_new_eq:NN \skip_zero:N  \dim_zero:N
+\cs_new_eq:NN \skip_gzero:N \dim_gzero:N
 \cs_generate_variant:Nn \skip_zero:N  { c }
 \cs_generate_variant:Nn \skip_gzero:N { c }
 %    \end{macrocode}
@@ -1856,9 +1853,9 @@
 %   Much the same as for dimensions.
 %    \begin{macrocode}
 \cs_new_protected:Npn \skip_set:Nn #1#2
-  { #1 ~ \tex_glueexpr:D #2 \scan_stop: }
+  { #1 = \tex_glueexpr:D #2 \scan_stop: }
 \cs_new_protected:Npn \skip_gset:Nn #1#2
-  { \tex_global:D #1 ~ \tex_glueexpr:D #2 \scan_stop: }
+  { \tex_global:D #1 = \tex_glueexpr:D #2 \scan_stop: }
 \cs_generate_variant:Nn \skip_set:Nn  { c }
 \cs_generate_variant:Nn \skip_gset:Nn { c }
 %    \end{macrocode}
@@ -1886,15 +1883,15 @@
 %   Using |by| here deals with the (incorrect) case |\skip123|.
 %    \begin{macrocode}
 \cs_new_protected:Npn \skip_add:Nn #1#2
-  { \tex_advance:D #1 by \tex_glueexpr:D #2 \scan_stop: }
+  { \tex_advance:D #1 \tex_glueexpr:D #2 \scan_stop: }
 \cs_new_protected:Npn \skip_gadd:Nn #1#2
-  { \tex_global:D \tex_advance:D #1 by \tex_glueexpr:D #2 \scan_stop: }
+  { \tex_global:D \tex_advance:D #1 \tex_glueexpr:D #2 \scan_stop: }
 \cs_generate_variant:Nn \skip_add:Nn  { c }
 \cs_generate_variant:Nn \skip_gadd:Nn { c }
 \cs_new_protected:Npn \skip_sub:Nn #1#2
-  { \tex_advance:D #1 by - \tex_glueexpr:D #2 \scan_stop: }
+  { \tex_advance:D #1 - \tex_glueexpr:D #2 \scan_stop: }
 \cs_new_protected:Npn \skip_gsub:Nn #1#2
-  { \tex_global:D \tex_advance:D #1 by - \tex_glueexpr:D #2 \scan_stop: }
+  { \tex_global:D \tex_advance:D #1 - \tex_glueexpr:D #2 \scan_stop: }
 \cs_generate_variant:Nn \skip_sub:Nn  { c }
 \cs_generate_variant:Nn \skip_gsub:Nn { c }
 %    \end{macrocode}
@@ -1911,7 +1908,7 @@
 %    \begin{macrocode}
 \prg_new_conditional:Npnn \skip_if_eq:nn #1#2 { p , T , F , TF }
   {
-    \str_if_eq:eeTF { \skip_eval:n { #1 } } { \skip_eval:n { #2 } }
+    \str_if_eq:eeTF { \skip_eval:n {#1} } { \skip_eval:n {#2} }
        { \prg_return_true: }
        { \prg_return_false: }
   }
@@ -1956,9 +1953,8 @@
 % \begin{macro}{\skip_use:N, \skip_use:c}
 %   Accessing a \meta{skip}.
 %    \begin{macrocode}
-\cs_new_eq:NN \skip_use:N \tex_the:D
-%\cs_generate_variant:Nn \skip_use:N { c }
-\cs_new:Npn \skip_use:c #1 { \tex_the:D \cs:w #1 \cs_end: }
+\cs_new_eq:NN \skip_use:N \dim_use:N
+\cs_new_eq:NN \skip_use:c \dim_use:c
 %    \end{macrocode}
 % \end{macro}
 %
@@ -2055,7 +2051,7 @@
 \cs_new_protected:Npn \muskip_const:Nn #1#2
   {
     \muskip_new:N #1
-    \tex_global:D #1 ~ \muskip_eval:n {#2} \scan_stop:
+    \tex_global:D #1 = \muskip_eval:n {#2} \scan_stop:
   }
 \cs_generate_variant:Nn \muskip_const:Nn { c }
 %    \end{macrocode}
@@ -2066,9 +2062,9 @@
 %   Reset the register to zero.
 %    \begin{macrocode}
 \cs_new_protected:Npn \muskip_zero:N #1
-  { #1 \c_zero_muskip }
+  { #1 = \c_zero_muskip }
 \cs_new_protected:Npn \muskip_gzero:N #1
-  { \tex_global:D #1 \c_zero_muskip }
+  { \tex_global:D #1 = \c_zero_muskip }
 \cs_generate_variant:Nn \muskip_zero:N  { c }
 \cs_generate_variant:Nn \muskip_gzero:N { c }
 %    \end{macrocode}
@@ -2108,9 +2104,9 @@
 %   This should be pretty familiar.
 %    \begin{macrocode}
 \cs_new_protected:Npn \muskip_set:Nn #1#2
-  { #1 ~ \tex_muexpr:D #2 \scan_stop: }
+  { #1 = \tex_muexpr:D #2 \scan_stop: }
 \cs_new_protected:Npn \muskip_gset:Nn #1#2
-  { \tex_global:D #1 ~ \tex_muexpr:D #2 \scan_stop: }
+  { \tex_global:D #1 = \tex_muexpr:D #2 \scan_stop: }
 \cs_generate_variant:Nn \muskip_set:Nn  { c }
 \cs_generate_variant:Nn \muskip_gset:Nn { c }
 %    \end{macrocode}
@@ -2144,15 +2140,15 @@
 %   Using |by| here deals with the (incorrect) case |\muskip123|.
 %    \begin{macrocode}
 \cs_new_protected:Npn \muskip_add:Nn #1#2
-  { \tex_advance:D #1 by \tex_muexpr:D #2 \scan_stop: }
+  { \tex_advance:D #1 \tex_muexpr:D #2 \scan_stop: }
 \cs_new_protected:Npn \muskip_gadd:Nn #1#2
-  { \tex_global:D \tex_advance:D #1 by \tex_muexpr:D #2 \scan_stop: }
+  { \tex_global:D \tex_advance:D #1 \tex_muexpr:D #2 \scan_stop: }
 \cs_generate_variant:Nn \muskip_add:Nn  { c }
 \cs_generate_variant:Nn \muskip_gadd:Nn { c }
 \cs_new_protected:Npn \muskip_sub:Nn #1#2
-  { \tex_advance:D #1 by - \tex_muexpr:D #2 \scan_stop: }
+  { \tex_advance:D #1 - \tex_muexpr:D #2 \scan_stop: }
 \cs_new_protected:Npn \muskip_gsub:Nn #1#2
-  { \tex_global:D \tex_advance:D #1 by - \tex_muexpr:D #2 \scan_stop: }
+  { \tex_global:D \tex_advance:D #1 - \tex_muexpr:D #2 \scan_stop: }
 \cs_generate_variant:Nn \muskip_sub:Nn  { c }
 \cs_generate_variant:Nn \muskip_gsub:Nn { c }
 %    \end{macrocode}
@@ -2174,8 +2170,8 @@
 % \begin{macro}{\muskip_use:N, \muskip_use:c}
 %   Accessing a \meta{muskip}.
 %    \begin{macrocode}
-\cs_new_eq:NN \muskip_use:N \tex_the:D
-\cs_generate_variant:Nn \muskip_use:N { c }
+\cs_new_eq:NN \muskip_use:N \dim_use:N
+\cs_new_eq:NN \muskip_use:c \dim_use:c
 %    \end{macrocode}
 % \end{macro}
 %
diff --git a/l3kernel/l3tl.dtx b/l3kernel/l3tl.dtx
index dad1f1587..141745d68 100644
--- a/l3kernel/l3tl.dtx
+++ b/l3kernel/l3tl.dtx
@@ -1317,9 +1317,9 @@
 %   Error checking is sorted out by the parent function.
 %    \begin{macrocode}
 \cs_new_protected:Npn \tl_clear:N  #1
-  { \tl_set_eq:NN #1 \c_empty_tl }
+  { \tex_let:D #1 = ~ \c_empty_tl }
 \cs_new_protected:Npn \tl_gclear:N #1
-  { \tl_gset_eq:NN #1 \c_empty_tl }
+  { \tex_global:D \tex_let:D #1 ~ \c_empty_tl }
 \cs_generate_variant:Nn \tl_clear:N  { c }
 \cs_generate_variant:Nn \tl_gclear:N { c }
 %    \end{macrocode}
@@ -1344,10 +1344,13 @@
 % \begin{macro}{\tl_set_eq:NN, \tl_set_eq:Nc, \tl_set_eq:cN, \tl_set_eq:cc}
 % \begin{macro}{\tl_gset_eq:NN, \tl_gset_eq:Nc, \tl_gset_eq:cN, \tl_gset_eq:cc}
 %   For setting token list variables equal to each other.  To allow for
-%   patching, the arguments have to be explicit.
+%   patching, the arguments have to be explicit.  In addition this
+%   ensures that a braced second argument will not cause problems.
 %    \begin{macrocode}
-\cs_new_protected:Npn \tl_set_eq:NN  #1#2 { \cs_set_eq:NN #1 #2 }
-\cs_new_protected:Npn \tl_gset_eq:NN #1#2 { \cs_gset_eq:NN #1 #2 }
+\cs_new_protected:Npn \tl_set_eq:NN  #1#2
+  { \tex_let:D #1 = ~ #2 }
+\cs_new_protected:Npn \tl_gset_eq:NN #1#2
+  { \tex_global:D \tex_let:D #1 = ~ #2 }
 \cs_generate_variant:Nn \tl_set_eq:NN { cN, Nc, cc }
 \cs_generate_variant:Nn \tl_gset_eq:NN { cN, Nc, cc }
 %    \end{macrocode}
@@ -1404,14 +1407,9 @@
 %   created the old-fashioned way.
 %    \begin{macrocode}
 \group_begin:
-\tex_lccode:D `A = `-
-\tex_lccode:D `N = `N
-\tex_lccode:D `V = `V
-\tex_lowercase:D
-  {
-    \group_end:
-    \tl_const:Nn \c_novalue_tl { ANoValue- }
-  }
+\tex_catcode:D `- = 11 ~
+\tl_const:Nx \c_novalue_tl { - NoValue \token_to_str:N - }
+\group_end:
 %    \end{macrocode}
 % \end{variable}
 %





More information about the latex3-commits mailing list.