启用\setmathfont后LuaLaTeX编译耗时过长的原因及优化方案
LuaLaTeX启用多数学字体后编译卡顿的原因与解决办法
问题现象
原本编译仅需10秒的LuaLaTeX文档,启用表格中注释的5行\setmathfont代码后,编译时间骤增至2分钟,环境为Windows下TeX Live 2022(含最新包),版本信息如下:
This is LuaHBTeX, Version 1.15.0 (TeX Live 2022) (format=lualatex 2022.12.10) 17 DEC 2022 20:53 restricted system commands enabled. LaTeX2e <2022-11-01> patch level 1 Lua module: luaotfload 2022-10-03 3.23 Lua based OpenType font support
核心原因
\setmathfont的高开销特性:每次调用该命令都会完整加载并初始化OpenType数学字体,包括解析字体内部的数学布局表、生成符号映射、预加载所有数学符号,这是CPU和IO密集型操作。- 表格内重复触发:原代码将
\setmathfont放在longtblr的表格行中,每一行都会触发一次完整的字体加载流程,5行就重复了5次高成本操作。 - tabularray的放大效应:
longtblr为了处理分页和动态布局,会对表格内容进行多次遍历排版,进一步放大了重复加载字体的开销。
解决办法
方案1:预定义数学字体版本(推荐)
通过unicode-math的version参数预定义所有需要的数学字体,后续仅需轻量切换版本,避免重复加载:
步骤1:在导言区预定义字体版本
\usepackage{unicode-math} % 预定义各数学字体的版本别名 \setmathfont[version=lmmath]{Latin Modern Math} \setmathfont[version=termes]{TeX Gyre Termes Math} \setmathfont[version=pagella]{TeX Gyre Pagella Math} \setmathfont[version=charter]{XCharter-Math.otf} \setmathfont[version=garamond]{Garamond-Math} \setmathfont[version=cambria]{Cambria Math} % 设置默认数学字体 \setmathfont{Latin Modern Math}
步骤2:表格内切换版本而非重新加载
% 表格中的数学字体演示行修改为: Latin Modern Math & \mathversion{lmmath} \mathstring \\ TeX Gyre Termes Math & \mathversion{termes} \mathstring \\ TeX Gyre Pagella Math & \mathversion{pagella} \mathstring \\ Charter - math version & \mathversion{charter} \mathstring \\ Garamond math version & \mathversion{garamond} \mathstring \\ Cambria Math & \mathversion{cambria} \mathstring \\
每个字体仅在预定义时加载一次,后续切换版本是极低开销的操作,编译时间会恢复至正常水平。
方案2:提前渲染公式并复用
通过\savebox提前渲染好每个数学字体对应的公式,再插入表格,彻底避免重复加载:
步骤1:提前渲染公式
在文档开头(\begin{document}之后)添加:
% 定义存储公式的盒子 \newsavebox{\lmmathbox} \savebox{\lmmathbox}{\setmathfont{Latin Modern Math} $\mathstring$} \newsavebox{\termesmathbox} \savebox{\termesmathbox}{\setmathfont{TeX Gyre Termes Math} $\mathstring$} \newsavebox{\pagellamathbox} \savebox{\pagellamathbox}{\setmathfont{TeX Gyre Pagella Math} $\mathstring$} \newsavebox{\chartermathbox} \savebox{\chartermathbox}{\setmathfont{XCharter-Math.otf} $\mathstring$} \newsavebox{\garamondmathbox} \savebox{\garamondmathbox}{\setmathfont{Garamond-Math} $\mathstring$} \newsavebox{\cambriamathbox} \savebox{\cambriamathbox}{\setmathfont{Cambria Math} $\mathstring$}
步骤2:表格内复用盒子
% 表格中的演示行修改为: Latin Modern Math & \usebox{\lmmathbox} \\ TeX Gyre Termes Math & \usebox{\termesmathbox} \\ TeX Gyre Pagella Math & \usebox{\pagellamathbox} \\ Charter - math version & \usebox{\chartermathbox} \\ Garamond math version & \usebox{\garamondmathbox} \\ Cambria Math & \usebox{\cambriamathbox} \\
额外优化提示
- 确保TeX Live的包保持更新,luaotfload后续版本对字体加载逻辑有性能优化。
- 避免在循环、表格行等重复执行的代码块中调用
\setmainfont、\setmathfont这类高开销命令。
内容的提问来源于stack exchange,提问作者Matthias Pospiech
相关产品推荐
相关产品推荐

