我可以做些什么来让 LuaLaTeX 编译得更快?(2022 年)

我可以做些什么来让 LuaLaTeX 编译得更快?(2022 年)

几年来我一直想问这个问题 - 而且我想现在是时候问了,因为上一次类似的问题是在 2017 年问的(据我所知)。

  • 我尝试过按照前面的答案建议的方式预编译格式。但我似乎无法让它与 一起工作fontspec

  • luajitlatex似乎不再存在 - 据称,这是由于 LuaJIT 不再积极开发,尽管我似乎已经能够找到一些分支(比如这个:https://github.com/fperrad/LuaJIT) 正在实现 Lua 5.3-5.4 的功能。但我不确定是否可以用这个分叉库进行luajittex编译。luajitlatex

  • 所有其他解决方案似乎都已过时(因为它们是近 10 年前的),而且我似乎无法在现代 TeX 发行版(2022 年)上复制答案。

虽然我知道(解释这个问题的先前答案)能够在几秒钟内编译整本书确实令人印象深刻lualatex,但我仍然对这个事实感到很恼火,lualatex无论文档如何,编译至少需要 1-2 秒,而pdflatex通常可以在 0.1 秒内编译相同的文档 - 而我唯一想做的就是使用 OpenType 字体和 UTF-8。(当然,这两个功能不会导致编译时间减慢 10-50 倍?)

如果我过度咆哮,请原谅 - 我知道 TeX 后端是一款老化的软件,但缺乏现代替代品或任何性能改进(据我所知)确实让我很难过。

lualatex如果我唯一想要的只是 OpenType 字体和 UTF-8,情况是否真的像看起来那么糟糕,或者是否有其他解决方案可以加快编译速度?

答案1

以下是如何慢的您的文档。示例首先创建一个小型 lua 模块mytimer.lua。要测量文档特定部分所需的时间,请写入\timerstart{name}\timerstop{name}。要打印统计信息的位置,请写入timer.statistics("document")。此文档大约需要 +20 秒才能打印 10 页。使用您自己的字体进行试验。字体LastResort可从 unicode github 页面下载。这不是一个非常准确的测试(因为它不测量 pdf 在屏幕上呈现所需的时间)。该代码能够通过主字体和的后备机制打印几乎所有的 Unicode 脚本luaotfloader

如果您注释掉对的调用\fontspec,并且除了花费 0.3 秒的时间之外不进行任何打印!因此,字体和资源密集型软件包(如 TikZ)将使编译速度减慢几个数量级。我也很高兴地报告,尽管 TeX 很老了,但它是一个非常快的程序,有关它因年限太长而减慢编译速度的谣言是假新闻。签名者可不这么认为!

\begin{filecontents*}[overwrite]{mytimer.lua}
-- table to hold time performance           
 M = M or {}
  local socket = require('socket')
  local time_stat = time_stat or {}
  local gettime = socket.gettime
   
-- start time measurement
time_stat["total"] = 0

-- @param done indicates timer was stopped
function start_time_measure(field)        
    time_stat[field] = {start = gettime(), done = false}
end

-- stop time measurement   
-- if two calls to stop will return wrong value
function stop_time_measure(field)         
    if not time_stat[field].done then 
       time_stat[field] = {total = gettime() - time_stat[field].start, done=true} 
    end   
end



 M.start = start_time_measure
 M.stop  = stop_time_measure 
 M.statistics = function(name) return time_stat[name].total end

-- M.start("document")
-- local s = 0
-- for i=1, 100000000 do s=s+1 end
-- M.stop("document")

-- print(M.statistics("document"))
-- print(M.statistics("document"))
return M
\end{filecontents*}

\directlua{timer = require("mytimer")}
\def\timerstart#1{\directlua{
timer.start("#1")}}
\def\timerstop#1{
\directlua{timer.stop("#1")}}

\def\timerprint#1{
\directlua{
timer.stop("#1")
tex.print("elapsed time (#1):", timer.statistics("#1"), "sec")
}}

\timerstart{document}

\documentclass{book}
\usepackage{fontspec}
\edef\mycolor{404547}
\directlua{luaotfload.add_fallback
("myfallback",
{  
   "NotoSansPahawhHmong:mode=harf;color=FF0000;",
   "NotoSansNko:mode=harf;color=FF0000;",
   "NotoSansAdlam:mode=harf;color=FF0000;",
   "NotoSansMarchen:mode=harf;color=\mycolor;",
   "NotoSansEthiopic:mode=harf;color=\mycolor;",
   "NotoSansSoyombo:mode=harf;color=\mycolor;",
   "NotoSansGrantha:mode=harf;color=0000FF;",
   "NotoSansBassaVah:mode=harf;color=\mycolor;",
   "NotoSansDeseret:mode=harf;", 
   "NotoSansOldHungarian:mode=harf;", 
   "NotoSansMeeteiMayek:mode=harf;",
   "NotoSansGurmukhi:mode=harf;color=\mycolor;", 
   "NotoSansOldTurkic:mode=harf;color=\mycolor;",
   "NotoSansChakma:mode=harf;color=\mycolor;",
   "NotoSansTelugu:mode=harf;color=\mycolor;", 
   "NotoSansSundanese:mode=harf;color=\mycolor;", 
   "NotoSansOsage:mode=harf;color=\mycolor;", 
   "NotoSansLao:mode=harf;color=\mycolor;",
   "NotoSansCaucasianAlbanian:mode=harf;color=FF0000;",
   "NotoSansTaiViet:mode=harf;color=\mycolor;",
   "NotoSerifTangut:mode=harf;color=\mycolor;",
   "NotoSansTifinagh:mode=harf;color=\mycolor;",
   "NotoSansTagbanwa:mode=harf;color=\mycolor;",
   "NotoSansTakri:mode=harf;color=\mycolor;",
   "NotoSansOlChiki:mode=harf;color=\mycolor;",
   "NotoSansLimbu:mode=harf;color=\mycolor;",
   "NotoSansKhmer:mode=harf;color=\mycolor;",
   "NotoSansCham:mode=harf;color=\mycolor;",
   "NotoSansJavanese:mode=harf;color=\mycolor;",
   "NotoSansSaurashtra:mode=harf;color=\mycolor;",
   "NotoSansTamil:mode=harf;color=\mycolor;",
   "NotoSansSamaritan:mode=harf;color=\mycolor;",
   "NotoSansBengali:mode=harf;script=bng2;color=0000FF;",
   "NotoSansMyanmar:mode=harf;script=bng2;color=0000FF;",
   "NotoSansBamum:mode=harf;color=0000FF;",
   "NotoSansDeseret:mode=harf;script=deseret;",
   "NotoSansMandaic-Regular:mode=harf;color=00FFFF;",
   "NotoSansOldSouthArabian:mode=harf;",
   "NotoSansOldNorthArabian:mode=harf;",
   "NotoSansImperialAramaic:mode=harf;",
   "NotoSansPalmyrene:mode=harf;color=\mycolor;",
   "NotoSansHatran:mode=harf;color=0000FF;",
   "NotoSansOldItalic:mode=harf;color=00FFFF;",
   "NotoSansRunic:mode=harf;color=\mycolor;",
   "NotoSansGothic:mode=harf;color=\mycolor;",
   "NotoSerifYezidi:mode=harf;color=00FF00;",
   "NotoSansYi:mode=harf;color=100000;",
   "Arial Unicode MS:mode=harf;",
   "DejaVuSans:mode=harf;script=grek;color=100000;",
   "cmuserif:mode=node;script=cyrl;color=101010;",
   "LastResort:mode=node;color=100010;",
 })}

\setmainfont{FreeSerif}[%
   Ligatures         = {Common,NoRare},%
   SmallCapsFeatures = {RawFeature=+c2sc},%
   Renderer          = Node,%
   Numbers           = Lining,%
   RawFeature={fallback=myfallback},
]


\newfontfamily\lastresort{LastResort}

\begin{document}


২০১৬ সাল থেকে এ পর্যন্ত সংস্থাটি ১৭টি উন্নয়নশীল দেশের ওপর মূল্যায়ন উপস্থাপন করেছে।\par


伯帛勃脖舶博渤霸壩灞

{\lastresort

ᠣᡳ  ᡳᠣᡳ᠊    ᠊ᡳᠣᡳ᠊   ᠊ᡳᠣᡳ

}

Anatolian 

\Uchar"14640

\directlua{for i=0x4E00, 0x6FFF do
tex.print(utf.char(i),", ")
end
}

\timerstop{document}

\directlua{tex.print("some test", timer.statistics("document"))}

\end{document}

答案2

这是另一个演示。

公平地比较,我只看到 lualatex 和 pdflatex 之间有 5 倍的差异。

我敢发誓,在我的某个文档中,lualatex 所花的时间比 pdflatex 长 10 倍。但是,当我从 lualatex 版本的文档(使用 fontspec 和不同的字体)中删除使用时addfontfeature,性能差异并没有那么大。

我的文档太大,无法发布,但下面的 Python 脚本将生成一个big.tex在某些方面类似的大文件。在我的 2014 年 Macbook Air 上,我看到这份 1150 页文档的编译时间如下:

  • pdflatex:5.530秒
  • lualatex: 29.158 秒

这是一个略大于 5 的倍数(我进行了三次试验,都在 5.2-5.3 倍范围内。)

#!/usr/bin/python

import sys

preamble8 = r"""\documentclass{article}
\makeatletter
\newcommand\myvn[1]{%
  \@ifnextchar A%
  {\textsuperscript{\itshape #1}\kern -.15em}%
  {\textsuperscript{\itshape #1}}}
\makeatother
\begin{document}
"""

phrases = ["The quick brown fox jumps over the lazy dog. ",
           "A lazy dog doesn't care. "
           ]

with open("big.tex", "w") as fp:
    fp.write(preamble8)
    for i in range(1, 100000):
        fp.write("\myvn{%d}" % (i % 42,))
        fp.write(phrases[i % len(phrases)])
        if i % 15 == 0:
            fp.write("\n\n")
        else:
            fp.write("\n")
    fp.write("\end{document}\n")

相关内容