不,传递表达式不需要额外的内存。与函数式语言一样,Mathematica 对象是不可变的:它们不能被修改,而是在您使用某些函数转换它们时创建一个新对象。这也意味着如果你不转换它们,它们就不会被复制,无论你在函数之间传递了多少。
从用户的角度来看,Mathematica 表达式是树,但我相信它们在内部存储为有向无环图,即相同的子表达式只能在内存中存储一次,无论它在完整表达式中出现多少次(参见例如的文档页面Share[]
)。
这里有一个例子来说明:
首先,确保In
/Out
不占用额外的内存:
In[1]:= $HistoryLength = 0;
检查内存使用情况:
In[2]:= MemoryInUse[]
Out[2]= 13421756
让我们做一个占用大量内存的表达式:
In[3]:= s = f@Range[1000000];
In[4]:= MemoryInUse[]
Out[4]= 17430260
现在重复这个表达式一百次......
In[5]:= t = ConstantArray[s, 100];
...并注意内存使用量几乎没有增加:
In[6]:= MemoryInUse[]
Out[6]= 18264676
ByeCount[]
具有误导性,因为它没有报告实际使用的物理内存,而是在不允许公共子表达式共享相同内存时使用的内存:
In[7]:= ByteCount[t]
Out[7]= 400018040
需要注意的一个有趣的点是:如果您从 中删除f[...]
,s
并同时创建s
和t
一个普通的数字数组,那么这种内存共享将不会发生,并且内存使用量将跃升至约 400 MB。
无论您是创建tree
全局变量还是 的参数getChildren
,它都不会影响内存使用。