[latex3-commits] [latex3/latex2e] gh1189: Support optimisation of long cmds (62d51295)

github at latex-project.org github at latex-project.org
Tue Nov 28 22:32:01 CET 2023


Repository : https://github.com/latex3/latex2e
On branch  : gh1189
Link       : https://github.com/latex3/latex2e/commit/62d512955111a94a6b8dae3d183de66ddeb0a48c

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

commit 62d512955111a94a6b8dae3d183de66ddeb0a48c
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Tue Nov 28 21:08:59 2023 +0000

    Support optimisation of long cmds


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

62d512955111a94a6b8dae3d183de66ddeb0a48c
 base/changes.txt                     |  4 ++-
 base/doc/usrguide.tex                |  5 ++++
 base/ltcmd.dtx                       | 55 ++++++++++++++++++++++++++----------
 base/testfiles-ltcmd/github-1009.tlg | 28 ++++++++----------
 base/testfiles-ltcmd/ltcmd001.tlg    | 12 ++++----
 5 files changed, 65 insertions(+), 39 deletions(-)

diff --git a/base/changes.txt b/base/changes.txt
index dc5e25e1..247c70c2 100644
--- a/base/changes.txt
+++ b/base/changes.txt
@@ -8,7 +8,9 @@ not part of the distribution.
 
 2023-11-28  Joseph Wright  <Joseph.Wright at latex-project.org>
 	* ltcmd.dtx (subsection{Declaring commands and environments}):
-	Optimise creation of simple document commands (gh/1189)
+	Optimize creation of simple document commands (gh/1189)
+	* usrguide.tex (subsection{Fully-expandable document commands}):
+	Document efficiency of ltcmd definitions
 
 2023-11-16  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
 	* ltpara.dtx (subsection{Providing hooks for paragraphs}):
diff --git a/base/doc/usrguide.tex b/base/doc/usrguide.tex
index 69428d96..57d56947 100644
--- a/base/doc/usrguide.tex
+++ b/base/doc/usrguide.tex
@@ -775,6 +775,11 @@ available:
     in the standard version.
 \end{itemize}
 
+When expandable commands have only |(+)m|-type arguments, the internal
+structure created is as-efficient as that provided by |\newcommand(*)|.
+As such, \cs{\NewExpandableDocumentCommand} may be used to replace
+\cs{newcommand} without concerns about performance.
+
 \subsection{Commands at the start of tabular cells}
 
 Creating commands that are used at the start of tabular cells imposes
diff --git a/base/ltcmd.dtx b/base/ltcmd.dtx
index cc8b34ff..1ced4c90 100644
--- a/base/ltcmd.dtx
+++ b/base/ltcmd.dtx
@@ -435,6 +435,26 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}[EXP]{\@@_all_m_check:n}
+% \begin{macro}[EXP]{\@@_all_m_check:w}
+%   A quick loop to check for all |(+)m|-type arguments.
+%    \begin{macrocode}
+\cs_new:Npn \@@_all_m_check:n #1
+  { \@@_all_m_check:w #1 \q_recursion_tail \q_recursion_stop }
+\cs_new:Npn \@@_all_m_check:w #1
+  {
+    \quark_if_recursion_tail_stop:n {#1}
+    \str_if_eq:nnF {#1} { m }
+      {
+        \str_if_eq:nnF {#1} { + }
+          { X }
+      }
+    \@@_all_m_check:w
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \begin{macro}{\@@_declare_cmd_code:Nnn}
 % \begin{macro}
 %   {
@@ -450,17 +470,17 @@
 %   optimised document command. This only applies to document commands,
 %   not creation of environments (which are more complex).
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_declare_cmd_code:Nnn
+\cs_new_protected:Npn \@@_declare_cmd_code:Nnn #1#2
   {
-    \bool_lazy_and:nnTF
-      { ! \l_@@_environment_bool }
+    \bool_lazy_all:nTF
       {
-        \str_if_eq_p:ee
-          { \exp_not:V \l_@@_signature_tl }
-          {
-            \prg_replicate:nn \l_@@_current_arg_int
-              { \exp_not:N \@@_expandable_grab_m:w }
-          }
+        { ! \l_@@_environment_bool }
+        {
+          ! \bool_lazy_and_p:nn
+            { \l_@@_some_short_bool }
+            { \l_@@_some_long_bool }
+        }
+        { \tl_if_blank_p:e { \@@_all_m_check:n {#2} } }
       }
       { \@@_declare_cmd_optimised:Nnn }
       {
@@ -468,18 +488,23 @@
           { \@@_declare_cmd_code_expandable:Nnn }
           { \@@_declare_cmd_code_aux:Nnn }
       }
+        #1 {#2}
    }
 %    \end{macrocode}
 %   The optimised version of commands just has to worry about whether to make
-%   them protected. The commands start with an expandable marker so that other
-%   parts of the kernel know these are set up by \pkg{ltcmd}
+%   them protected or long. The commands start with an expandable marker so
+%   that other parts of the kernel know these are set up by \pkg{ltcmd}.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_declare_cmd_optimised:Nnn #1#2#3
   {
-    \bool_if:NTF \l_@@_expandable_bool
-      { \cs_generate_from_arg_count:NNnn #1 \cs_set_nopar:Npn }
-      { \cs_generate_from_arg_count:NNnn #1 \cs_set_protected_nopar:Npn }
-        \l_@@_current_arg_int { \@@_start_optimised: #3 }
+    \exp_args:NNc \cs_generate_from_arg_count:NNnn #1
+      {
+        cs_set
+        \bool_if:NF \l_@@_expandable_bool { _protected }
+        \bool_if:NF \l_@@_some_long_bool { _nopar }
+        :Npn
+      }
+      \l_@@_current_arg_int { \@@_start_optimised: #3 }
   }
 \cs_new:Npn \@@_start_optimised: { }
 %    \end{macrocode}
diff --git a/base/testfiles-ltcmd/github-1009.tlg b/base/testfiles-ltcmd/github-1009.tlg
index 35d0e6b5..4983b91c 100644
--- a/base/testfiles-ltcmd/github-1009.tlg
+++ b/base/testfiles-ltcmd/github-1009.tlg
@@ -21,15 +21,13 @@ l. ...}
 #1->\__cmd_start_optimised: .
 <argument> \baz 
 l. ...}
-> \foo=document command:
-  #1:+m
-->.
-<recently read> }
+> \foo=\protected\long macro:
+#1->\__cmd_start_optimised: .
+<argument> \foo 
 l. ...}
-> \baz=document command:
-  #1:+m
-->.
-<recently read> }
+> \baz=\protected\long macro:
+#1->\__cmd_start_optimised: .
+<argument> \baz 
 l. ...}
 > \foo=document command:
   #1:>{\foo }m
@@ -63,14 +61,12 @@ l. ...}
 #1->\__cmd_start_optimised: .
 <argument> \baz 
 l. ...}
-> \foo=expandable document command:
-  #1:+m
-->.
-<recently read> }
+> \foo=\long macro:
+#1->\__cmd_start_optimised: .
+<argument> \foo 
 l. ...}
-> \baz=expandable document command:
-  #1:+m
-->.
-<recently read> }
+> \baz=\long macro:
+#1->\__cmd_start_optimised: .
+<argument> \baz 
 l. ...}
 ============================================================
diff --git a/base/testfiles-ltcmd/ltcmd001.tlg b/base/testfiles-ltcmd/ltcmd001.tlg
index 517d0a8a..25399448 100644
--- a/base/testfiles-ltcmd/ltcmd001.tlg
+++ b/base/testfiles-ltcmd/ltcmd001.tlg
@@ -107,11 +107,10 @@ l. ...}
 ============================================================
 TEST 4: Commands with one long mandatory argument
 ============================================================
-> \foo=\protected macro:->\__cmd_start_expandable:nNNNNn {+m}\foo  \foo  \foo
-code ?{\__cmd_expandable_grab_m_long:w }.
+> \foo=\protected\long macro:#1->\__cmd_start_optimised: (#1).
 <recently read> }
 l. ...}
-> \foo code=\protected\long macro:#1->(#1).
+> \foo code=undefined.
 <recently read> }
 l. ...}
 > \foo=\protected macro:->\__cmd_start_expandable:nNNNNn {m+m}\foo  \foo  
@@ -331,17 +330,16 @@ l. ...}
 > \foo code=undefined.
 <recently read> }
 l. ...}
-> \foo=macro:->\__cmd_start_expandable:nNNNNn {+m}\foo  \foo  \foo code
-?{\__cmd_expandable_grab_m_long:w }.
+> \foo=\long macro:#1->\__cmd_start_optimised: (#1).
 <recently read> }
 l. ...}
-> \foo code=\long macro:#1->(#1).
+> \foo code=undefined.
 <recently read> }
 l. ...}
 > \foo=macro:#1#2#3->\__cmd_start_optimised: (#1)(#2)(#3).
 <recently read> }
 l. ...}
-> \foo code=\long macro:#1->(#1).
+> \foo code=undefined.
 <recently read> }
 l. ...}
 > \foo=macro:->\__cmd_start_expandable:nNNNNn {om}\foo  \foo  \foo code





More information about the latex3-commits mailing list.