TeX/LaTeX 中新宏或命令的数量是否有限制

TeX/LaTeX 中新宏或命令的数量是否有限制

新定义的数量是否有上限,例如

\def\myNewDefA{foo}
\def\myNewDefB{bar}
...
\newcommand\myNewMacroA{foo}
\newcommand\myNewMacroB{bar}

可以使用 pdflatex 排版文档吗?

答案1

TeX 有很多内存限制。

以下 iniTeX 的 TeX 文件测试了其中的一些:

% test.tex
% iniTeX
% preamble
\tracingstats=1
\catcode`\{=1
\catcode`\}=2  
\countdef\i=255
\countdef\m=100
\chardef\l=1
\def\e{}
\i=0
\def\n{%
  \ifnum\i<\m
    \advance\i\l%
    \expandafter\let\csname x\the\i\endcsname\e
  \else
    \let\n\end
  \fi
  \n
}
% main
\m=0 % number of macro definitions
\n
% end of test.tex

测试文件定义了\m形式为、等的宏。\x1它们通过定义来定义,不占用定义内存,因为它与宏(在本例中为空宏)共享。\x2\x3\let\e

运行后(例如tex --ini test)该文件test.log包含一段简短的内存统计信息。

一些例子:

\m=0

Here is how much of TeX's memory you used:
 4 strings out of 498654
 30 string characters out of 6225568
 1060 words of memory out of 5000000
 322 multiletter control sequences out of 15000+600000
 7 words of font info for 0 fonts, out of 8000000 for 9000
 0 hyphenation exceptions out of 8191
 1i,0n,0p,54b,6s stack positions out of 5000i,500n,10000p,200000b,80000s

\m=100000

Here is how much of TeX's memory you used:
 100004 strings out of 498654
 588925 string characters out of 6225568
 1074 words of memory out of 5000000
 100322 multiletter control sequences out of 15000+600000
 7 words of font info for 0 fonts, out of 8000000 for 9000
 0 hyphenation exceptions out of 8191
 3i,0n,0p,54b,6s stack positions out of 5000i,500n,10000p,200000b,80000s

\m=498654

Here is how much of TeX's memory you used:
 498654 strings out of 498654
 3379475 string characters out of 6225568
 1074 words of memory out of 5000000
 498972 multiletter control sequences out of 15000+600000
 7 words of font info for 0 fonts, out of 8000000 for 9000
 0 hyphenation exceptions out of 8191
 3i,0n,0p,54b,6s stack positions out of 5000i,500n,10000p,200000b,80000s

pdftex --ini test已经失败:

! TeX capacity exceeded, sorry [number of strings=497943].

琴弦数量(max_strings

TeX Live 2013 使用max_strings=500000texmf.cnf一些字符串被占用(原语名称,...)。测试文件中定义的宏名称使用不存储为字符串的短单字符/字母命令名称。字符串存储为内存池的索引。

可以增加字符串的数量,例如(bash):

$ max_strings=1000000 tex --ini test

但是哈希表的限制是命中(\m=800000):

! TeX capacity exceeded, sorry [hash size=615000].

哈希表大小(hash_extra

每个命令名称也存储在哈希表中,以便快速访问。其大小15000可以增加hash_extra600000在 TL 2013 中)。

$ max_strings=1000000 hash_extra=1000000 tex --ini test

现在适用于\m=800000

Here is how much of TeX's memory you used:
 800004 strings out of 998654
 5488925 string characters out of 6225568
 1074 words of memory out of 5000000
 800322 multiletter control sequences out of 15000+1000000
 7 words of font info for 0 fonts, out of 8000000 for 9000
 0 hyphenation exceptions out of 8191
 3i,0n,0p,54b,6s stack positions out of 5000i,500n,10000p,200000b,80000s

池大小 ( pool_size)

字符串字符实际存放的内存是字符串池,其大小也是有限的(pool_sizeTL 2013 中默认值为6250000)。

使用\m=1500000以下命令

$ max_strings=1600000 hash_extra=1600000 pool_size=16000000 tex --ini test

成功

Here is how much of TeX's memory you used:
 1500004 strings out of 1598654
 10888926 string characters out of 15975568
 1076 words of memory out of 5000000
 1500322 multiletter control sequences out of 15000+1600000
 7 words of font info for 0 fonts, out of 8000000 for 9000
 0 hyphenation exceptions out of 8191
 3i,0n,0p,54b,6s stack positions out of 5000i,500n,10000p,200000b,80000s

主存储器(main_memory

对于非平凡的定义,主内存也被使用。以下行

\expandafter\edef\csname x\the\i\endcsname{\the\i}%

使用包含数字的定义文本定义宏\x1\x2\x3

\m=1000000和的结果

$ max_strings=1600000 hash_extra=1600000 pool_size=16000000 main_memory=10000000 tex --ini test

Here is how much of TeX's memory you used:
 1000004 strings out of 1598654
 6888926 string characters out of 15975568
 7889966 words of memory out of 10000000
 1000322 multiletter control sequences out of 15000+1600000
 7 words of font info for 0 fonts, out of 8000000 for 9000
 0 hyphenation exceptions out of 8191
 3i,0n,0p,62b,6s stack positions out of 5000i,500n,10000p,200000b,80000s

但是主内存不能无限增加,例如使用main_memory=15000000会导致内部致命错误:

Ouch---my internal constants have been clobbered!---case 14

概括

TeX 是在内存非常有限且昂贵且计算机速度非常慢的时代编写的。因此,Knuth 编写了自己的内存管理,使用固定大小的表,如果达到最大大小,则不会动态增长。一些表大小可以增加TeX 运行。但仍存在一些实施限制。

LuaTeX

LuaTeX 重写了 TeX 的核心,因此一些限制已经消失。最新示例\m=1500000运行于

$ max_strings=1600000 hash_extra=1600000 luatex --ini test

并使用以下内存(0.76.0):

Here is how much of LuaTeX's memory you used:
 1500013 strings out of 1598958
 500,14696376 words of node,token memory allocated
 58 words of node memory still in use:
    nodes
   avail lists: 2:1,6:1
 1500335 multiletter control sequences out of 65536+1600000
 0 fonts using 0 bytes
 3i,0n,0p,61b,6s stack positions out of 5000i,500n,10000p,200000b,100000s

相关内容