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

Skip to content

Commit 9b74f28

Browse files
committed
Use luatex in --luaonly mode to query kpsewhich.
`luatex --luaonly` runs a *lua* interpreter with relevant tex libraries available, which avoids 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 319f24f commit 9b74f28

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The *format* parameter of ``dviread.find_tex_file``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
... is deprecated (with no replacement).

lib/matplotlib/dviread.py

Lines changed: 33 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

@@ -981,7 +982,30 @@ def _parse_enc(path):
981982
"Failed to parse {} as Postscript encoding".format(path))
982983

983984

985+
class _LuatexKpsewhich:
986+
@lru_cache() # A singleton.
987+
def __new__(cls):
988+
self = object.__new__(cls)
989+
self._proc = self._new_proc()
990+
return self
991+
992+
def _new_proc(self):
993+
return subprocess.Popen(
994+
["luatex", "--luaonly",
995+
str(cbook._get_data_path("kpsewhich.lua"))],
996+
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
997+
998+
def search(self, filename):
999+
if self._proc.poll() is not None: # Dead, restart it.
1000+
self._proc = self._new_proc()
1001+
self._proc.stdin.write(os.fsencode(filename) + b"\n")
1002+
self._proc.stdin.flush()
1003+
out = self._proc.stdout.readline().rstrip()
1004+
return "" if out == b"nil" else os.fsdecode(out)
1005+
1006+
9841007
@lru_cache()
1008+
@_api.delete_parameter("3.5", "format")
9851009
def find_tex_file(filename, format=None):
9861010
"""
9871011
Find a file in the texmf tree.
@@ -999,6 +1023,7 @@ def find_tex_file(filename, format=None):
9991023
format : str or bytes
10001024
Used as the value of the ``--format`` option to :program:`kpsewhich`.
10011025
Could be e.g. 'tfm' or 'vf' to limit the search to that type of files.
1026+
Deprecated.
10021027
10031028
References
10041029
----------
@@ -1013,6 +1038,14 @@ def find_tex_file(filename, format=None):
10131038
if isinstance(format, bytes):
10141039
format = format.decode('utf-8', errors='replace')
10151040

1041+
if format is None:
1042+
try:
1043+
lk = _LuatexKpsewhich()
1044+
except FileNotFoundError:
1045+
pass # Fallback to directly calling kpsewhich, as below.
1046+
else:
1047+
return lk.search(filename)
1048+
10161049
if os.name == 'nt':
10171050
# On Windows only, kpathsea can use utf-8 for cmd args and output.
10181051
# 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)