vpack 是否昂贵?:使用混合 latex 和 luatex 代码进行细粒度性能测量/分析

vpack 是否昂贵?:使用混合 latex 和 luatex 代码进行细粒度性能测量/分析

如何使用混合 latex、luatex 代码进行细粒度性能测量?假设有两个代码块,一个接一个地执行。第一个是纯 latex,第二个是 luatex。我想知道添加第二段代码的实际开销。我想到的一个测试用例是对现有 vbox 执行 vpack,该 vbox 最初未设置为其内容的大小。与 vbox 创建相比,vpack 有多昂贵?这实际上是我感兴趣的,尤其是对于巨大的 vbox 来说。这是我需要插入性能计时器的代码(在标记位置):

(注意:忽略 tempvbox 的“自然高度”值,由于高度超出了 tex 限制,因此它是不正确的。当然,您可以通过将盲文中的段落数从 1000 减少到较小的值来看到正确的值,尽管这也会降低所考虑的两个时间增量比率的准确性。)

% >> lualatex <filename>.tex
\documentclass[notitlepage,letterpaper]{article}
\usepackage[english]{babel}
\usepackage{blindtext}
\usepackage{printlen}
\setlength\parindent{0pt}
\uselengthunit{in}

\begin{document}

% Time1
\newsavebox{\tempvbox}
\setbox\tempvbox=\vbox to 4in{{\hsize=4in \noindent\blindtext[1000]}}

% Time2
\directlua{
    tempvboxnatural = node.vpack(tex.getbox('tempvbox').head)
}%
% Time3

Set height of tempvbox: \directlua{tex.sprint("\csstring\%f  in",(tex.getbox('tempvbox').height/tex.sp('1in')))}

Natural Height of tempvbox: \directlua{tex.sprint("\csstring\%f  in",(tempvboxnatural.height/tex.sp('1in')))}

%Print Time2-Time1, and Time3-Time2 here
Time2-Time1: ??

Time3-Time2: ??

Partial contents of tempvbox:

\vsplit\tempvbox to 6in

\end{document}

输出截图:

编译输出的屏幕截图

答案1

根据 Marcel Krüger 和 Patrick Gundlach (topskip) 的建议,经过一些补充和测试,以下是最终的代码和观察结果:

对于长度只有几行的段落(\blindtext[1]),vpack 占用其各自 vbox 创建时间的 2% 到 10%。随着行数的增加(\blindtext[1000]或循环\blindtext[1]\par\blindtext[1]\par...),vpack 相对于 vbox 创建所花费的时间百分比不断下降(因为\blindtext[1000]它大约是 vbox 创建所花费时间的 0.01%)。无论哪种方式,百分比上的 vpack 似乎微不足道,因为可以预期 vbox 创建的复杂度为 O(n^2),而 vpack 的复杂度可能是 O(n)。

\documentclass[notitlepage,letterpaper]{article}
\usepackage[english]{babel}
\usepackage{blindtext}
\usepackage{printlen}
\usepackage{tikz}
\setlength\parindent{0pt}
\uselengthunit{in}

\begin{document}

% Time1
\directlua{time1 = os.clock(); texio.write_nl("time = " .. time1)}
\newsavebox{\tempvbox}
\setbox\tempvbox=\vbox to 4in{{\hsize=4in \blindtext[1]}}

% Time2
\directlua{time2 = os.clock(); texio.write_nl("time = " .. time2)}
\directlua{
    tempvboxnatural = node.vpack(tex.getbox('tempvbox').head)
}%
% Time3
\directlua{time3 = os.clock(); texio.write_nl("time = " .. time3)}

\directlua{texio.write_nl("(time3-time2)*100/(time2-time1) = " .. (time3-time2)*100/(time2-time1) .. " \csstring\%" )}


Set height of tempvbox: \directlua{tex.sprint(-2,string.format("\csstring\%f  in",(tex.getbox('tempvbox').height/tex.sp('1in'))))}

Natural Height of tempvbox: \directlua{tex.sprint(-2,string.format("\csstring\%f  in",(tempvboxnatural.height/tex.sp('1in'))))}

%Print Time2-Time1, and Time3-Time2 here
Delta1 (Time2-Time1): \directlua{tex.sprint(time2-time1)}

Delta2 (Time3-Time2): \directlua{tex.sprint(time3-time2)}

(Delta2/Delta1)*100: \directlua{tex.sprint((time3-time2)*100/(time2-time1))} \%

Partial contents of tempvbox:

\vsplit\tempvbox to 6in

\end{document}

截屏:

编译输出的屏幕截图

相关内容