Matlab中cell和matrix有什么区别?

31

在Matlab中,“cell”(即带有{ })和“matrix”(即带有[ ])之间有什么区别?

1个回答

35

在MATLAB中,cell array和matrix之间有几个区别:

  • 每个单元格中的元素类型可以是任意类型的,而矩阵要求其元素类型是同质的即相同类型。

  • 就内存布局而言,矩阵中的所有元素都是按照连续的方式排列在内存中,而cell array包含对数组中每个元素的指针。这在考虑到高性能代码的缓存局部性时可能很重要。

  • 第2点的反面是,当您调整矩阵的大小时,必须将矩阵中的每个元素复制到新分配的内存区域中,但是在cell array的情况下,只需要复制指针列表。根据您存储的元素的大小和类型,这可能意味着cell数组的调整大小速度更快。


为了说明内存布局上的差异,让我们考虑一个简单的例子:

A = [10 20 30 40];

MATLAB在这里创建了一个名为A的新矩阵变量,分配了足够的内存来容纳4个双精度浮点数(32字节,假设每个双精度浮点数为8字节),并将该内存分配给指向A的部分的指针。(如果您创建了一个复数矩阵,内存也将用于部分,并且将有一个单独的指针指向该内存区域)。

现在让我们创建一个包含这些元素的单元数组:

B = cell(1, 4);
B{1,1} = 10;
B{1,2} = 20;
B{1,3} = 30;
B{1,4} = 40;
当 MATLAB 执行第一条语句时,它创建了一个单元数组,其中包含 4 个指针,每个指针都可以指向任意类型。因此,B 已经使用了 16 个字节(假设为 32 位指针)。 下一行创建一个包含值为 10 的 1x1 矩阵,并将其赋值给第一个单元数组元素。这里的过程类似于我上面描述的创建 1x4 矩阵的过程,只是分配的内存只足够容纳一个 double(8 个字节)。对于剩余的三个语句也是如此。所以,至少,第二个示例使用了 16 + 8 x 4 = 48 个字节。 请注意,MATLAB 中的每个变量还包括用于存储有关该变量的维度、数据类型等信息的结构体 mxArray 的内存开销。出于简单起见,我忽略了这个开销。

1
有几个要点需要注意...... 对于像 B 这样的 cell 数组来说,过于具体地说它存储指针是不恰当的。从概念上讲,cell 类型的变量就像指针一样,但 Matlab 并没有记录它们在 mxArray 中的具体实现方式。我们只知道它们在内部带有一些开销。Matlab 会告诉你关于开销的一些信息:输入 a = []; c = {a}; whos 命令,Matlab 将会报告 c 变量所使用的字节数。我认为这大约是每个 mxArray 所带来的开销。 - Andrew Janke
1
事实上,它以这种方式报告,并结合在调试器中查看地址和MAT文件格式等因素,让我认为mxArrays单元可能实际上直接存储了C数组的mxArray结构(其中的头部分),而不是指针。 - Andrew Janke
此外,我知道这有点挑剔,但在Matlab中,每个原始或复合数组都有一个mxArray,而不是每个变量。B是一个变量。它保存了一个4长的单元格数组,每个单元格元素包含一个双精度数组。因此,B的数据结构中有5个mxArrays。这就是为什么单元格和结构最终可能会使用大量开销的原因,您可以使用whos建议的每个mxarray开销来近似。 - Andrew Janke
1
@AndrewJanke 我在我的回答中确实做了一些概括。我同意,每个“值”(我认为那不是正确的术语,但想不出更好的术语),而不是“变量”,都有自己的 mxArray 标头。MATLAB 并没有记录任何关于类型内部表示的信息,除了暗示存在 mxArray,将其称为不透明类型并将其留在那里。关于单元数组类型包含标头数组而不是指向每个标头的指针的部分,对我来说是新闻,很高兴你发表了评论。 - Praetorian
是的,mxArray类型是不透明且未记录的。(并且可能在版本之间更改。) 我对它的理解是基于C mx函数的外部接口文档、7.3之前的二进制MAT文件格式(完全记录)以及查看MEX文件和调试器中的mxArray内存。我怀疑在内存中的mxArray布局看起来很像MAT文件布局,并且在运行时在内存中窥视一下也与此一致。是的,“value”也不太对。也许是“array”? - Andrew Janke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接