Lua,tex.print 是否只累积

Lua,tex.print 是否只累积

我可以先构建输出,然后使用 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 秒。这再次表明基准测试很棘手,在解释结果时应小心谨慎。

相关内容