problemas de memoria después de la migración a texlive 2016 y forest 2.0

problemas de memoria después de la migración a texlive 2016 y forest 2.0

Tengo un libro de más de 800 páginas y se compila bien con xelatex y forest 1.05 en texlive 2015. Estoy migrando a texlive 2016 ya que mi traductor trabaja con forest 2.0. Ahora obtengo:

! TeX capacity exceeded, sorry [pool size=6143546].
\safeiterate@4 ...@countc y\endcsname )\endcsname 
                                              \forest@inpath      \forest@tem...
l.770 }

Si elimino el código del bosque, aparece el error más tarde. Si envío porciones más pequeñas, todo está bien. Entonces supongo que realmente es un problema de memoria.

Pregunta: ¿Hay algo que pueda hacer además de modificar algunos archivos de configuración de tex? Se supone que el código se ejecuta para varios usuarios y tener que modificar las variables de memoria sería malo.

Lo siento, no hay un ejemplo mínimo aquí, pero podría hacer que el código esté disponible en github o en otro lugar.

Editar: OK. Debe ser forest 2.0 ya que cuando cargo forest 1.05 mientras ejecuto texlive 2016, todo está bien.

Respuesta1

De hecho, se trataba de un problema forestal, pero, sorprendentemente, ha estado presente desde la primera versión del paquete. Stefan fue simplemente el primero en crear un documento tan largo y lleno de árboles... y el cambio de v1 a v2 no hizo más que llevar el problema al límite.

Antes de explicar qué salió mal: acabo de publicar la versión corregida (v2.1.4) en CTAN.

El problema fue precisamente el que mencionó Ulrike Fischer en un comentario anterior. El algoritmo de empaquetado de Forest necesita almacenar (temporalmente) cierta información sobre coordenadas (y pares de coordenadas). Además, dada una coordenada (o un par), necesita recuperar la información sobre ella rápidamente. La solución obvia es almacenar la información en un diccionario (matriz asociativa), siendo las coordenadas la clave de búsqueda, por lo que usar las secuencias de control de TeX parecía una idea perfecta y lo hice ingenuamente (esencialmente copié y pegué desde mi implementación de Python de prueba de concepto). ):

\csdef{forest@(\the\pgf@x,\the\pgf@y)}{...}

e incluso

\csdef{forest@(\the\pgf@xa,\the\pgf@ya)--(\the\pgf@xb,\the\pgf@yb)}{...}

sin darse cuenta de que aunque las definiciones son locales, las entradas permanecerán en la tabla hash de TeX para siempre. Este enfoque consumió fácilmente unos pocos kilobytes de espacio del grupo de cadenas.por árbol!

v2.1.4 vuelve a implementar los diccionarios infractores almacenando toda la información en un único registro toks, cuyo contenido se ve así (se muestra solo para el primero de los problemas anteriores):

...(x1,y1){...}(x2,y2){...}...

Es fácil buscar una coordenada específica en dicha estructura (aunque más lento que en \csnameaproximación):

\def\forest@breakpath@getfromtoks#1#2#3#4{%
  % #1=cache toks register, #2=receiving cs, (#3,#4)=point;
  % we rely on the fact that the point we're looking up should always be present
  \def\forest@breakpath@getfromtoks@##1(#3,#4)##2##3\forest@END{##2}%
  \edef#2{\expandafter\forest@breakpath@getfromtoks@\the#1\forest@END}%

(Muchos paquetes utilizan dicho sistema, consulte, por ejemplo,\PGFs \pgfutil@in@).

El nuevo sistema es aproximadamente un 10% más lento, pero: en el libro de más de 800 páginas de Stefan, donde la versión v2.1.3 excedió el límite del grupo de cadenas de caracteres de 6 millones, la v2.1.4 (y todos los demás paquetes cargados) consume apenas 2 millones. . Con respecto al consumo de memoria por parte del algoritmo de empaquetado, la longitud del documento ya no importa.

Stefan, ¡gracias por encontrar esto y soportarme durante la semana pasada! (Pista: mirando el algoritmo de empaquetado nuevamente después de estos dos años, ¡creo que también podría hacerse mucho más rápido!)

información relacionada