[latex3-commits] [git/LaTeX3-latex3-latex3] main: Speed up l3clist N-type mappings (582270fe3)
Bruno Le Floch
blflatex at gmail.com
Sat May 15 02:15:27 CEST 2021
Repository : https://github.com/latex3/latex3
On branch : main
Link : https://github.com/latex3/latex3/commit/582270fe3b0c3c83951389d447e274f36eab7232
>---------------------------------------------------------------
commit 582270fe3b0c3c83951389d447e274f36eab7232
Author: Bruno Le Floch <blflatex at gmail.com>
Date: Sat May 15 02:15:27 2021 +0200
Speed up l3clist N-type mappings
The speed up is around 2-8 times (largest for larger comma lists)
>---------------------------------------------------------------
582270fe3b0c3c83951389d447e274f36eab7232
l3kernel/CHANGELOG.md | 2 +-
l3kernel/l3clist.dtx | 96 ++++++++++++++++++++++++++++-----------------------
2 files changed, 54 insertions(+), 44 deletions(-)
diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md
index 44677a176..029a2291d 100644
--- a/l3kernel/CHANGELOG.md
+++ b/l3kernel/CHANGELOG.md
@@ -20,7 +20,7 @@ this project uses date-based 'snapshot' version identifiers.
- Checking brace balance in all regex functions (issue #377)
### Changed
-- Speed up mapping functions in l3tl, l3seq, l3prop
+- Speed up mapping functions in l3clist, l3prop, l3seq, l3tl
## [2021-05-11]
diff --git a/l3kernel/l3clist.dtx b/l3kernel/l3clist.dtx
index 16142c3f1..4b3684308 100644
--- a/l3kernel/l3clist.dtx
+++ b/l3kernel/l3clist.dtx
@@ -1654,28 +1654,38 @@
%
% \begin{macro}{\clist_map_function:NN, \clist_map_function:cN}
% \UnitTested
-% \begin{macro}{\@@_map_function:nw}
+% \begin{macro}{\@@_map_function:Nw, \@@_map_function_end:w}
% If the variable is empty, the mapping is skipped (otherwise,
% that comma-list would be seen as consisting of one empty item).
-% Then loop over the comma-list, grabbing one comma-delimited
-% item at a time. The end is marked by \cs{q_@@_recursion_tail}.
-% The auxiliary function \cs{@@_map_function:nw} is also used
-% in \cs{clist_map_inline:Nn}.
+% Then loop over the comma-list, grabbing eight comma-delimited items
+% at a time. The end is marked by \cs{s_@@_stop}, which may not appear
+% in any of the items. Once the last group of eight items has been
+% reached, we go through them more slowly using
+% \cs{@@_map_function_end:w}. The auxiliary function
+% \cs{@@_map_function:Nw} is also used in some other clist mappings.
% \begin{macrocode}
\cs_new:Npn \clist_map_function:NN #1#2
{
\clist_if_empty:NF #1
{
- \exp_last_unbraced:NNo \@@_map_function:nw #2 #1
- , \q_@@_recursion_tail ,
+ \exp_after:wN \@@_map_function:Nw \exp_after:wN #2 #1 ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
\prg_break_point:Nn \clist_map_break: { }
}
}
-\cs_new:Npn \@@_map_function:nw #1#2 ,
+\cs_new:Npn \@@_map_function:Nw #1 #2, #3, #4, #5, #6, #7, #8, #9,
{
- \@@_if_recursion_tail_break:nN {#2} \clist_map_break:
+ \@@_use_none_delimit_by_s_stop:w
+ #9 \@@_map_function_end:w \s_@@_stop
+ #1 {#2} #1 {#3} #1 {#4} #1 {#5} #1 {#6} #1 {#7} #1 {#8} #1 {#9}
+ \@@_map_function:Nw #1
+ }
+\cs_new:Npn \@@_map_function_end:w \s_@@_stop #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \clist_map_break: \s_@@_stop
#1 {#2}
- \@@_map_function:nw {#1}
+ \@@_map_function_end:w \s_@@_stop
}
\cs_generate_variant:Nn \clist_map_function:NN { c }
% \end{macrocode}
@@ -1736,9 +1746,11 @@
\int_gincr:N \g__kernel_prg_map_int
\cs_gset_protected:cpn
{ @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2}
- \exp_last_unbraced:Nco \@@_map_function:nw
+ \exp_last_unbraced:Nco \@@_map_function:Nw
{ @@_map_ \int_use:N \g__kernel_prg_map_int :w }
- #1 , \q_@@_recursion_tail ,
+ #1 ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
\prg_break_point:Nn \clist_map_break:
{ \int_gdecr:N \g__kernel_prg_map_int }
}
@@ -1756,59 +1768,57 @@
% \begin{macro}{\clist_map_variable:NNn, \clist_map_variable:cNn}
% \UnitTested
% \begin{macro}{\clist_map_variable:nNn}
-% \begin{macro}{\@@_map_variable:Nnw}
-% As for other comma-list mappings, filter out the case of
-% an empty list. Same approach as \cs{clist_map_function:Nn},
-% additionally we store each item in the given variable.
-% As for inline mappings, space trimming for the \texttt{n}
-% variant is done by storing the comma list in a variable.
-% The quark test is done before assigning the item to the variable:
-% this avoids storing a quark which the user wouldn't expect.
-% The strange \cs{use:n} avoids unlikely problems when |#2| would
-% contain \cs{q_@@_recursion_stop}.
+% \begin{macro}{\@@_map_variable:Nnn}
+% The |N|-type version is a straightforward application of
+% \cs{clist_map_tokens:Nn}, calling \cs{@@_map_variable:Nnn} for each
+% item to assign the variable and run the user's code. The |n|-type
+% version is \emph{not} implemented in terms of the |n|-type function
+% \cs{clist_map_tokens:Nn}, because here we are allowed to clean up
+% the |n|-type comma list non-expandably.
% \begin{macrocode}
\cs_new_protected:Npn \clist_map_variable:NNn #1#2#3
- {
- \clist_if_empty:NF #1
- {
- \exp_args:Nno \use:nn
- { \@@_map_variable:Nnw #2 {#3} }
- #1
- , \q_@@_recursion_tail , \q_@@_recursion_stop
- \prg_break_point:Nn \clist_map_break: { }
- }
- }
+ { \clist_map_tokens:Nn #1 { \@@_map_variable:Nnn #2 {#3} } }
+\cs_generate_variant:Nn \clist_map_variable:NNn { c }
+\cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3
+ { \tl_set:Nn #1 {#3} #2 }
\cs_new_protected:Npn \clist_map_variable:nNn #1
{
\clist_set:Nn \l_@@_internal_clist {#1}
\clist_map_variable:NNn \l_@@_internal_clist
}
-\cs_new_protected:Npn \@@_map_variable:Nnw #1#2#3,
- {
- \@@_if_recursion_tail_stop:n {#3}
- \tl_set:Nn #1 {#3}
- \use:n {#2}
- \@@_map_variable:Nnw #1 {#2}
- }
-\cs_generate_variant:Nn \clist_map_variable:NNn { c }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\clist_map_tokens:Nn, \clist_map_tokens:cn}
-% \begin{macro}{\@@_map_tokens:nw}
+% \begin{macro}{\@@_map_tokens:nw, \@@_map_tokens_end:w}
% Essentially a copy of \cs{clist_map_function:NN} with braces added.
% \begin{macrocode}
\cs_new:Npn \clist_map_tokens:Nn #1#2
{
\clist_if_empty:NF #1
{
- \exp_last_unbraced:Nno \@@_map_function:nw {#2} #1
- , \q_@@_recursion_tail ,
+ \exp_last_unbraced:Nno \@@_map_tokens:nw {#2} #1 ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
\prg_break_point:Nn \clist_map_break: { }
}
}
+\cs_new:Npn \@@_map_tokens:nw #1 #2, #3, #4, #5, #6, #7, #8, #9,
+ {
+ \@@_use_none_delimit_by_s_stop:w
+ #9 \@@_map_tokens_end:w \s_@@_stop
+ \use:n {#1} {#2} \use:n {#1} {#3} \use:n {#1} {#4} \use:n {#1} {#5}
+ \use:n {#1} {#6} \use:n {#1} {#7} \use:n {#1} {#8} \use:n {#1} {#9}
+ \@@_map_tokens:nw {#1}
+ }
+\cs_new:Npn \@@_map_tokens_end:w \s_@@_stop \use:n #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \clist_map_break: \s_@@_stop
+ #1 {#2}
+ \@@_map_tokens_end:w \s_@@_stop
+ }
\cs_generate_variant:Nn \clist_map_tokens:Nn { c }
% \end{macrocode}
% \end{macro}
More information about the latex3-commits
mailing list.