Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4775421

Browse files
committed
Use luatex in --luaonly mode to query kpsewhich.
`luatex --luaonly` runs a *lua* interpreter with relevant tex libraries available, which avoids both the overhead of repeatedly initializing kpathsea (the old approach, very slow on macos and windows). An alternative approach would be to use `luatex` followed by `\directlua` calls, but on windows it appears that one needs to use `lualatex` to get a working interactive prompt, and just loading the latex format takes seconds(!). For the simple following benchmark: ```sh python -c 'from pylab import *; mpl.use("pdf"); rcParams["text.usetex"] = True; plot(); savefig("test.pdf", backend="pdf")' ``` On a macos machine, this patch brings runtime from ~4.5s to ~2.5s. On a windows machine, this patch brings runtime from ~6.5s to ~1.7s. We also need to figure out how to best advertise this (do we emit a warning suggesting to install luatex on windows and macos if luatex is not present?).
1 parent 266be12 commit 4775421

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

lib/matplotlib/dviread.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from pathlib import Path
2626
import re
2727
import struct
28+
import subprocess
2829
import sys
2930
import textwrap
3031

@@ -1040,6 +1041,28 @@ def _parse_enc(path):
10401041
"Failed to parse {} as Postscript encoding".format(path))
10411042

10421043

1044+
class _LuatexKpsewhich:
1045+
@lru_cache() # A singleton.
1046+
def __new__(cls):
1047+
self = object.__new__(cls)
1048+
self._proc = self._new_proc()
1049+
return self
1050+
1051+
def _new_proc(self):
1052+
return subprocess.Popen(
1053+
["luatex", "--luaonly",
1054+
str(cbook._get_data_path("kpsewhich.lua"))],
1055+
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
1056+
1057+
def search(self, filename):
1058+
if self._proc.poll() is not None: # Dead, restart it.
1059+
self._proc = self._new_proc()
1060+
self._proc.stdin.write(os.fsencode(filename) + b"\n")
1061+
self._proc.stdin.flush()
1062+
out = self._proc.stdout.readline().rstrip()
1063+
return "" if out == b"nil" else os.fsdecode(out)
1064+
1065+
10431066
@lru_cache()
10441067
def find_tex_file(filename, format=None):
10451068
"""
@@ -1072,6 +1095,14 @@ def find_tex_file(filename, format=None):
10721095
if isinstance(format, bytes):
10731096
format = format.decode('utf-8', errors='replace')
10741097

1098+
try:
1099+
lk = _LuatexKpsewhich()
1100+
except FileNotFoundError:
1101+
pass # Fallback to directly calling kpsewhich, as below.
1102+
else:
1103+
return lk.search(
1104+
f"{filename}.{format}" if format is not None else filename)
1105+
10751106
if os.name == 'nt':
10761107
# On Windows only, kpathsea can use utf-8 for cmd args and output.
10771108
# The `command_line_encoding` environment variable is set to force it

lib/matplotlib/mpl-data/kpsewhich.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-- see dviread._LuatexKpsewhich
2+
kpse.set_program_name("tex")
3+
while true do print(kpse.lookup(io.read():gsub("\r", ""))) end

0 commit comments

Comments
 (0)