令牌寄存器与宏寄存器

令牌寄存器与宏寄存器

考虑以下简单的代码:

\def\@ifundefined#1#2#3{% \cs{UNDEF}{DEF}
    \def\reserved@a{#2}%
    \def\reserved@b{#3}%
    \ifdefined#1
        \let\reserved@c\reserved@b
    \else
        \let\reserved@c\reserved@a
    \fi
    \reserved@c}

使用以下方法可以达到同样的效果:

\toksdef\tokszero0
\toksdef\tokstwo2
\def\@@ifundefined#1#2#3{% \cs{UNDEF}{DEF}
    \tokszero{#2}%
    \tokstwo{#3}%
    \ifdefined#1
        \let\reserved@c\tokstwo
    \else
        \let\reserved@c\tokszero
    \fi
    \the\reserved@c}

有什么显著的区别吗?(除了\toksdef。)哪一个更可取?

(我能想到一个区别。如果 UNDEF 或 DEF 包含#,则宏寄存器版本将会失败。)

答案1

虽然不是一个非常完整的基准,但它应该能给出一些想法。考虑以下testundef.tex文件

\catcode`@=11

\def\a@ifundefined#1#2#3{% \cs{UNDEF}{DEF}
  \def\reserved@a{#2}%
  \def\reserved@b{#3}%
  \ifdefined#1%
    \let\reserved@c\reserved@b
  \else
    \let\reserved@c\reserved@a
  \fi
  \reserved@c
}
\toksdef\tokszero0
\toksdef\tokstwo2
\def\b@ifundefined#1#2#3{% \cs{UNDEF}{DEF}
  \tokszero{#2}%
  \tokstwo{#3}%
  \ifdefined#1%
    \let\reserved@c\tokstwo
  \else
    \let\reserved@c\tokszero
  \fi
  \the\reserved@c
}
\def\@firstoftwo#1#2{#1}
\def\@secondoftwo#1#2{#2}
\def\c@ifundefined#1{% \cs{UNDEF}{DEF}
  \ifdefined#1%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

\expandafter\let\expandafter\ifundefined\csname\test @ifundefined\endcsname

\count255=0
\loop\ifnum\count255<1000000
  \ifundefined\foo{\relax}{\relax}
  \ifundefined\relax{\relax}{\relax}
  \advance\count255 1
\repeat

\bye

我给出了三种可能的定义\@ifundefined,然后通过命令行开关进行测试。以下是会话记录

> time pdftex "\def\test{a}\input testundef"
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) (preloaded format=pdftex)
 restricted \write18 enabled.
entering extended mode
(./testundef.tex )
No pages of output.
Transcript written on testundef.log.

real    0m1.871s
user    0m1.844s
sys 0m0.018s

> time pdftex "\def\test{b}\input testundef"
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) (preloaded format=pdftex)
 restricted \write18 enabled.
entering extended mode
(./testundef.tex )
No pages of output.
Transcript written on testundef.log.

real    0m2.308s
user    0m2.277s
sys 0m0.021s

> time pdftex "\def\test{c}\input testundef"
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) (preloaded format=pdftex)
 restricted \write18 enabled.
entering extended mode
(./testundef.tex )
No pages of output.
Transcript written on testundef.log.

real    0m1.518s
user    0m1.490s
sys 0m0.017s

看起来该\toks方法是最慢的;最后一种方法,采用纯扩展,速度更快,因为不需要进行存储和检索。

相关内容