我可以先构建输出,然后使用 tex.print,也可以对每个字符串使用 tex.print。这会降低性能吗?
使用 tex.print 比构建字符串更容易,但如果速度很慢(数千次调用),那么就不值得。
答案1
我尝试了一个小型基准测试,似乎使用 连接..
比 重复 要快一点tex.print
。请注意,这是一个非常简单的基准测试,如果涉及其他因素,性能可能会发生变化,例如,如果连接的字符串变得很长,排版可能比一串较短的字符串更复杂(有换行符/连字符、段落布局等)。
首先使用 (Linux) 进行基准测试time lualatex testfile.tex
,计算整个过程的时间。下面的代码连接了 10 个字符串,其中一个是随机数,以防止缓存,无论是使用..
运算符还是重复tex.print
调用。此操作重复 50,000 次,生成 1087 页输出。
\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
function dotconcat()
a = "abc "
c = "def "
d = "ghi "
e = "\\par"
for i=1,50000 do
b = math.random(1000)
x = a .. b .. c .. d .. a .. b .. c .. d .. a .. b .. e
tex.print(x)
end
end
function texprintconcat()
a = "abc "
c = "def "
d = "ghi "
e = "\\par"
for i=1,50000 do
b = math.random(1000)
tex.print(a) tex.print(b)
tex.print(c) tex.print(d)
tex.print(a) tex.print(b)
tex.print(c) tex.print(d)
tex.print(a) tex.print(b)
tex.print(e)
end
end
\end{luacode*}
\begin{document}
% either
\directlua{dotconcat()}
% or
%\directlua{texprintconcat()}
\end{document}
计时结果如下dotconcat()
:
real 0m6,548s
user 0m6,435s
sys 0m0,108s
和texprintconcat()
:
real 0m7,016s
user 0m6,890s
sys 0m0,120s
第二个基准测试是l3benchmark
,仅测量函数调用中使用的时间:
\documentclass{article}
\usepackage{luacode}
\usepackage{l3benchmark}
\begin{luacode*}
function dotconcat()
a = "abc "
c = "def "
d = "ghi "
e = "\\par"
b = math.random(1000)
x = a .. b .. c .. d .. a .. b .. c .. d .. a .. b .. e
tex.print(x)
end
function texprintconcat()
a = "abc "
c = "def "
d = "ghi "
e = "\\par"
b = math.random(1000)
tex.print(a) tex.print(b)
tex.print(c) tex.print(d)
tex.print(a) tex.print(b)
tex.print(c) tex.print(d)
tex.print(a) tex.print(b)
tex.print(e)
end
\end{luacode*}
\begin{document}
\ExplSyntaxOn
\benchmark_once:n{%
\prg_replicate:nn {50000} {\directlua{dotconcat()}}% or texprintconcat()
}
\ExplSyntaxOff
\end{document}
结果:
dotconcat()
7.98 seconds (3.03e7 ops)
texprintconcat()
8.16 seconds (2.61e7 ops)
请注意,基准测试本身会为编译增加另外 1 秒。差异在 200 毫秒 ( l3benchmark
) 和 400 毫秒 (Linux time
) 之间,占总数的百分之几 - 因此不能完全忽略不计,但也不是很重要。
编辑:为了简化我在代码上使用的基准测试代码\benchmark_once:n{\directlua{dotconcat()}}
(和 for 相同texprintconcat()
),并使用 for 循环来放大结果:
dotconcat: 8.93 seconds (2.84e7 ops)
texprintconcat: 9.9 seconds (2.8e7 ops)
尽管操作数现在更加相等,但所用时间tex.print
现在比..
以前多了 1 秒。这再次表明基准测试很棘手,在解释结果时应小心谨慎。