problemas de memória após migração para texlive 2016 e floresta 2.0

problemas de memória após migração para texlive 2016 e floresta 2.0

Eu tenho um livro com mais de 800 páginas e ele compila bem com xelatex e floresta 1.05 no texlive 2015. Estou migrando para o texlive 2016 porque meu tradutor trabalha com floresta 2.0. Agora eu entendo:

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

Se eu remover o código florestal, recebo o erro mais tarde. Se eu enviar porções menores, tudo ficará bem. Então eu acho que realmente é um problema de memória.

Pergunta: Há algo que eu possa fazer além de modificar alguns arquivos de configuração do tex? O código deve ser executado para vários usuários e ter que modificar variáveis ​​de memória seria ruim.

Desculpe, não há um exemplo mínimo aqui, mas eu poderia disponibilizar o código no github ou em outro lugar.

Editar: OK. Deve ser a floresta 2.0, pois quando carrego a floresta 1.05 durante a execução do texlive 2016, está tudo bem.

Responder1

Esta era de facto uma questão florestal, mas, surpreendentemente, está presente desde a primeira versão do pacote. Stefan foi simplesmente o primeiro a criar um documento tão longo e cheio de árvores... e a mudança da v1 para a v2 não fez nada além de levar o problema ao limite.

Antes de explicar o que deu errado: acabei de postar a versão corrigida (v2.1.4) no CTAN.

O problema foi precisamente o que Ulrike Fischer mencionou num comentário acima. O algoritmo de empacotamento de Forest precisa armazenar (temporariamente) algumas informações sobre coordenadas (e pares de coordenadas). Além disso, dada uma coordenada (ou um par), ele precisa recuperar rapidamente as informações sobre ela. A solução óbvia é armazenar as informações em um dicionário (matriz associativa), com as coordenadas sendo a chave de pesquisa, portanto, usar as sequências de controle do TeX parecia uma ideia perfeita e eu ingenuamente o fiz (essencialmente copiar e colar da minha implementação python de prova de conceito ):

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

e até mesmo

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

sem perceber que embora as definições sejam locais, as entradas permanecerão na tabela hash do TeX para sempre. Essa abordagem consumiu facilmente alguns kilobytes de espaço no pool de stringspor árvore!

A v2.1.4 reimplementa os dicionários problemáticos, armazenando todas as informações em um único registro toks, cujo conteúdo se parece com este (mostrado apenas para o primeiro dos problemas acima):

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

É fácil procurar uma coordenada específica em tal estrutura (embora mais lento que na \csnameabordagem):

\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}%

(Muitos pacotes usam tal sistema, veja por exemplo\ PGFs \pgfutil@in@.)

O novo sistema é cerca de 10% mais lento, mas: no livro de mais de 800 páginas de Stefan, onde a versão v2.1.3 excedeu o limite de 6 milhões de conjuntos de strings de caracteres, a v2.1.4 (e todos os outros pacotes carregados) consome apenas 2 milhões . Com relação ao consumo de memória pelo algoritmo de empacotamento, o comprimento do documento não importa mais.

Stefan, obrigado por encontrar isso e me acompanhar durante a semana passada! (Dica: olhando novamente para o algoritmo de empacotamento após alguns anos, acredito que ele também poderia ser feito muito mais rápido!)

informação relacionada