![TeX/LaTeX 中新宏或命令的数量是否有限制](https://linux22.com/image/273340/TeX%2FLaTeX%20%E4%B8%AD%E6%96%B0%E5%AE%8F%E6%88%96%E5%91%BD%E4%BB%A4%E7%9A%84%E6%95%B0%E9%87%8F%E6%98%AF%E5%90%A6%E6%9C%89%E9%99%90%E5%88%B6.png)
新定义的数量是否有上限,例如
\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=500000
。texmf.cnf
一些字符串被占用(原语名称,...)。测试文件中定义的宏名称使用不存储为字符串的短单字符/字母命令名称。字符串存储为内存池的索引。
可以增加字符串的数量,例如(bash):
$ max_strings=1000000 tex --ini test
但是哈希表的限制是命中(\m=800000
):
! TeX capacity exceeded, sorry [hash size=615000].
哈希表大小(hash_extra
)
每个命令名称也存储在哈希表中,以便快速访问。其大小15000
可以增加hash_extra
(600000
在 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_size
TL 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