Open hmenke opened 5 years ago
Here is a simple plain TeX reproducer of the problem.
\input luaotfload.sty
\def\mainfont{SourceSerifPro-Regular.otf}
\long\def\onum#1{%
\begingroup
\expandafter\font\csname\mainfont:+onum\endcsname="\mainfont:+onum" at 10pt
\csname\mainfont:+onum\endcsname#1%
\endgroup
}
\newcount\counter
\counter=0
\loop\ifnum\counter<10000
\onum{123}\endgraf
\advance\counter by 1
\repeat
\bye
On my machine this takes 7.968s to typeset. However, when I replace the definition of \onum
by
\long\def\onum#1{%
\begingroup
\ifcsname\mainfont:+onum\endcsname\else
\global\expandafter\font\csname\mainfont:+onum\endcsname="\mainfont:+onum" at 10pt
\fi
\csname\mainfont:+onum\endcsname#1%
\endgroup
}
it suddenly only takes 0.796s!
Thanks for the detailed analysis! I am embarrassed to admit that I thought at some point I did eliminate the inefficiency here — but either I didn't do it correctly or it is a false memory.
I'll do what I can to correct this quickly; I have a few fontspec issues piling up at the moment...
If possible you should add a switch to disable the caching. It might be that LuaTeX garbage-collects unused \font
s, so if you are using like a thousand different fonts in your document, the caching might actually hurt you. Not a common use-case for sure, but maybe something to keep in mind.
Has there been any progress on this? Sorry for poking. I am facing this with documents where I use old style num except for siunitx numbers and in tables where lining numbers are used. However, with this configuration, it adds at least 50% to the compilation time. It would be great to have some update.
@wspr Apologies for poking as well, but has there been any progress on this - since it's been almost a year and a half since the last reply?
Would appreciate it if a reply could be made here, even if there has been no progress yet.
@kwand — apologies, I'm having a hard time juggling family and work at the moment and TeX work has slipped behind. I couldn't promise a timeframe for an update on this, I'm sorry.
I know you guys are busy and have lives, but I am hoping to give this a bump in case it's been forgotten. I'm the asker of the original question on tex.stackexchange that prompted @hmenke to figure out this issue and report it. The performance hit I see on real documents is annoying but not unlivable, but it is annoying.
Description
The
\addfontfeature
command does not cache fonts at global scope. Why is this important? It turns out that users don't seem to be aware that\addfontfeature
reloads the whole font from disk with adjusted features and that is absolutely detrimental for typesetting performance. Even worse, commands that seem innocuous, like\textsuperscript
can become real monsters, when, in this case by loading therealscripts
package, adding\addfontfeature
to the definition of\textsuperscript
and thus reloads the whole font on every invocation!However, the usage of
\addfontfeature
seems to me mostly to be done programmatically, i.e. inside a macro with always the exact same set of features. It seems, therefore, advantageous to cache fonts at the macro level. It could also be done in the font loader, which might be possible for LuaTeX, but since XeTeX development has basically been abandoned, there is not much chance there.Check/indicate
Minimal example demonstrating the issue
An example for this issue can't be minimal because the problem really only manifests when
\addfontfeature
is called many times. However, we can have a minimal example generator, which is only a few lines of Lua. Here I just read a dictionary from disk. On Linux/usr/share/dict/words
is a file with one word per line.Running
will generate a file, similar to this:
Note that I deliberately chose
Style=Alternate
as a font feature, because Source Serif Pro actually does not have this feature, which worsens the problem because for each time the font is loaded from disk, a multiline warning message has to be written to the log, increasing the amount of disk I/O and slowing down the process further.Running this in LuaTeX generates the following timing on my machine
However, just adding
after
\begin{document}
, the timing reduces toThat is a whopping 20 times speedup!
Further details
In fact, if you keep scaling this up, the huge number local macro definitions from
expl3
falls on your feet. In this TeX.SX question, the user actually ran out ofstrings
: https://tex.stackexchange.com/questions/517505A related topic is Release space in the string pool.