проблемы с памятью после миграции на texlive 2016 и forest 2.0

проблемы с памятью после миграции на texlive 2016 и forest 2.0

У меня есть книга на 800+ страниц, и она отлично компилируется с xelatex и forest 1.05 под texlive 2015. Я перехожу на texlive 2016, так как мой переводчик работает с forest 2.0. Теперь я получаю:

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

Если я удаляю код леса, то получаю ошибку позже. Если я тексую меньшие порции, то все нормально. Так что я думаю, что это действительно проблема с памятью.

Вопрос: Могу ли я что-то сделать, кроме как изменить некоторые файлы конфигурации tex? Код должен работать для нескольких пользователей, и необходимость изменять переменные памяти была бы плохой.

Извините, здесь нет минимального примера, но я могу выложить код на github или где-нибудь еще.

Редактировать: ОК. Это должен быть лес 2.0, так как когда я загружаю лес 1.05 при запуске texlive 2016, все в порядке.

решение1

Это действительно была проблема леса, но, как ни странно, она присутствовала с самой первой версии пакета. Стефан был просто первым, кто создал такой длинный, полный дерева документ... и переход с v1 на v2 не сделал ничего, кроме как вытолкнул проблему за край.

Прежде чем объяснить, что пошло не так: я только что опубликовал исправленную версию (v2.1.4) на CTAN.

Проблема была именно в том, о чем Ульрике Фишер упомянула в комментарии выше. Алгоритм упаковки Forest должен (временно) хранить некоторую информацию о координатах (и парах координат). Более того, имея координату (или пару), ему нужно быстро извлекать информацию о ней. Очевидным решением является сохранение информации в словаре (ассоциативном массиве), где координаты будут ключом поиска, поэтому использование управляющих последовательностей TeX показалось мне идеальной идеей, и я наивно так и сделал (по сути, скопировав-вставив из моей реализации Python для проверки концепции):

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

и даже

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

не понимая, что хотя определения локальны, записи останутся в хэш-таблице TeX навсегда. Такой подход легко израсходовал несколько килобайт пространства пула строкза дерево!

В версии 2.1.4 повторно реализованы проблемные словари путем сохранения всей информации в одном регистре toks, содержимое которого выглядит следующим образом (показано только для первой из вышеперечисленных проблем):

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

В такой структуре легко искать определенную координату (хотя и медленнее, чем при \csnameприближении):

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

(Многие пакеты используют такую ​​систему, см. например\ PGFs \pgfutil@in@.)

Новая система примерно на 10% медленнее, но: в книге Стефана объемом более 800 страниц, где версия v2.1.3 превысила лимит пула строк в 6 миллионов символов, v2.1.4 (и все остальные загруженные пакеты) использует всего 2 миллиона. Что касается потребления памяти алгоритмом упаковки, длина документа больше не имеет значения.

Стефан, спасибо, что нашел это и терпел меня всю прошлую неделю! (Подсказка: взглянув на алгоритм упаковки по-новому спустя несколько лет, я считаю, что его можно было бы сделать намного быстрее!)

Связанный контент