考虑以下简单的代码:
\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
方法是最慢的;最后一种方法,采用纯扩展,速度更快,因为不需要进行存储和检索。