vpacks は高価ですか?: LaTeX と Luatex の混合コードで細粒度のパフォーマンス測定/プロファイリングを行う

vpacks は高価ですか?: LaTeX と Luatex の混合コードで細粒度のパフォーマンス測定/プロファイリングを行う

混合 LaTeX と LuAtex コードで、きめ細かなパフォーマンス測定を行うにはどうすればよいでしょうか。2 つのコード ブロックがあり、それらが次々に実行されるとします。1 つ目はプレーンな LaTeX で、2 つ目は LuAtex です。2 つ目のコードを追加することによる実際のオーバーヘッドを知りたいと思います。思いつくテスト ケースは、元々コンテンツのサイズに設定されていなかった既存の vbox で vpack を実行することです。vbox の作成と比較して、vpack はどのくらいコストがかかりますか。これは、特に巨大な vbox の場合など、実際に知りたいことです。パフォーマンス タイマーの挿入が必要なコードは次のとおりです (マークされた場所):

(注: tempvbox の「自然な高さ」の値は無視してください。高さが tex 制限を超えているため、正しくありません。もちろん、ブラインドテキストの段落数を 1000 から小さい値に減らすことで正しい値を確認できますが、これにより、考慮する 2 つの時間デルタの比率の精度も低下します。)

% >> 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...)、vbox 作成と比較した vpack にかかる時間の割合は減少し続けます ( \blindtext[1000]vbox 作成にかかる時間の 0.01% 程度であるため)。いずれにしても、vbox 作成は O(n^2) の複雑さで、vpack はおそらく O(n) の複雑さであると予想されるため、割合で見ると vpack は重要ではないようです。

\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}

スクリーンショット:

コンパイルされた出力のスクリーンショット

関連情報