[Tex/LaTex] How to speed up LuaLaTeX startup with fontspec

fontspecinitexluatexperformance

As a novice user of lualatex and fontspec I've found it very slow (>1.3 seconds) to load on my Linux system:

% This is file compact.tex
\documentclass[a4paper]{article}
% This is needed only for old (non-fontspec) fonts.
%\usepackage[utf8]{luainputenc}
\usepackage{fontspec}
\newfontfamily\myverdana{Verdana.ttf}[]
% 1.38s user time up to this point.
% \makeatletter\@@end
\begin{document}
\hrule
{\Huge Helló, Wörld, árvíztűrő}
\hrule
{\Huge Helló, Wörld, árvízt\H{u}r\H{o}}
\hrule
{\myverdana\Huge Helló, Wörld, árvíztűrő}
\hrule
\end{document}
% 1.44s user time up to this point.

My time measurements:

  • pdflatex (without fontspec): 0.04 seconds in total to generate the .pdf file
  • lualatex without fontspec: 0.25 seconds to reach \begin{document}, then 0.01 seconds extra to generate the .pdf file
  • lualatex with fontspec: 1.38 seconds to reach \begin{document}, then 0.06 seconds extra to generate the .pdf file. See example file above.
  • lualatex with fontspec, with expl3.sty preloaded by lualatex --ini: 0.50 seconds to reach \begin{document}, then 0.05 seconds extra to generate the .pdf file. See example files below.
  • lualatex with fontspec, with mylatexformat.ltx: 0.28 seconds to reach \begin{document}, then 0.07 seconds to generate the .pdf file.

Is there a way to make lualatex startup with fontspec and a font already loaded faster than 1.38 seconds?

I tried calling \dump just before \begin{document}, but when I attempted to load the .fmt file, I got an error stating that some Lua code wasn't available.

(Maybe I can try dumping and restoring the entire Linux process.)

I'm asking because we are implementing a web service which compiles short (1–2 page) LaTeX documents to PDF, and we'd like to have a fast solution (which finishes quickly and uses little CPU on the server). Upgrading from pdflatex to lualatex would make it about 10 times slower for our short documents, which is too slow.

FYI Here is how I used mylatexformat.ltx. I generated luaheader.fmt with (should work on both Linux and Windows):

$ luatex -interaction=nonstopmode -ini -jobname=luaheader "&lualatex" mylatexformat.ltx compact.tex

Then I compiled the compact.tex document to .pdf with either of these:

$ luatex "&luaheader" compact
$ lualatex --fmt luaheader compact

FYI Here are my source files using lualatex --ini manually:

% This is half1.tex, compile it with:
% $ lualatex --ini half1.tex
\let\OLDdump\dump
\let\dump\relax
\input lualatex.ini
\let\dump\OLDdump
\let\OLDselectfont\selectfont
% \selectfont called by \normalsize defined and called by size10.clo loaded
% by article.cls. If we don't change \selectfont here, we get an error
% message: ! Font \TU/lmr/m/n/10=[lmroman10-regular]:+tlig; at 10pt not
% loadable: metric data not found or bad.
\def\selectfont{\baselineskip12pt }
\documentclass[a4paper]{article}
\let\selectfont\OLDselectfont
\usepackage{expl3}
\usepackage{xparse}
% This fails in initex with: [\directlua]:1: attempt to index global
% 'luatexbase' (a nil value)
%\usepackage{luatexbase}
% This fails in initex with:
% ...ive/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua:176: attempt
% to index global 'luatexbase' (a nil value)
%\usepackage{luaotfload}  % Needs luaotfload to work.
% This needs luaotfload.
%\usepackage{fontspec}  % Needs luaotfload to work.
% This needs luatexbase.
%\usepackage[utf8]{luainputenc}
\dump

and

% This is half2.tex, compile it with:
% $ lualatex --fmt half1 half2
\normalsize
% This is needed only for old (non-fontspec) fonts.
%\usepackage[utf8]{luainputenc}
\usepackage{fontspec}
\newfontfamily\myverdana{Verdana.ttf}[]
% 0.50s user time up to this point.
% \makeatletter\@@end
\begin{document}
\hrule
{\Huge Helló, Wörld, árvíztűrő}
\hrule
{\Huge Helló, Wörld, árvízt\H{u}r\H{o}}
\hrule
{\myverdana\Huge Helló, Wörld, árvíztűrő}
\hrule
\end{document}
% 0.55s user time for half2.tex up to this point.

Best Answer

If your documents use the same preamble, maybe you can save time using a prebuild format.

I produced a prebuild format and tested (texlive 2018, updated) your file:

  1. Let's say the filename is myjob.tex. Then produce the format with this command on the command line (Peter, as far as I know you are on Linux, I tested on Windows):

    luatex -interaction=nonstopmode -ini -jobname="luaheader" "&lualatex" mylatexformat.ltx ""myjob.tex""

  2. Put this text as first line of the file you want to compile: %&luaheader.

OK, probably you have many different file names and I don't have a clue how to adapt this code here to that.

And more important, I'm not sure if you really save much time, because I don't know how to measure compilation times correctly.

By the way: many many thanks for pdfsizeopt, which really has been helpfull for so many years and still is indispensable!

Related Question