[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.