我几十年来一直在使用Matlab。我认为我对数组,结构,单元数组,表,结构数组以及每个字段都是数组的结构有很好的控制。对于后两者,我假设每个领域都需要是统一的类型。我发现没有这样的限制:
也许Matlab这些年来变得越来越灵活(我使用2015b),但如果我发现对每种类型的局限性的理解是,那么它确实会削弱我为任务选择最佳变量类型的信心。错误。出于这个问题的目的,我无法明确表达任务的需求,因为我将大量待办事项分解为任务的方式取决于我对我所掌握的数据类型的理解以及它们的优势/限制。
我可以(并且已经)阅读在线文档广告,虽然他们会引导您完成代码以说明数据类型能够做什么,但我还没有看到对比限制的简洁描述在单元格数组,结构数组和结构数组之间,它们的字段本身就是数组 - 我可以利用这些知识在给定的情况下选择最佳结构。基本的东西,我发现,例如,结构数组的每个结构中都会出现相同的字段名称(但如上例所示,每个结构的每个字段都可以包含高度异构的数据类型和/或数组大小)。 p>
问题
任何人都可以指出单元格数组,结构数组和标量结构之间的限制比较,其字段本身就是数组吗?我正在寻找一种能够在(i)速度,(ii)记忆和(iii)可读性,可维护性和可进化性之间做出最佳平衡的程度的治疗方法。
我故意遗漏了表格,因为虽然我很喜欢他们方便地访问和分组数据集(及其表示),但事实证明他们对数据的操纵相当慢。它们有它们的用途,我自由地使用它们,但是我对这些比较的目的并不感兴趣,这就是引擎盖下的算法编码。
答案 0 :(得分:4)
我认为你的问题最终会缩小到这三种类型"数据结构:
单元格数组,结构数组和结构之间的比较限制,其fiels本身就是数组
[注意"结构域,其字段本身就是数组"我翻译为"标量结构"这里。结构数组也可以包含任意数组。我的希望在下面明确我的想法。]
对我来说,这些并没有太大的不同。这三个都是异构数据的容器。 (异构数据是非统一数据,每个数据元素可能具有不同的类型和大小。)这些语句中的每一个都可以返回任何类型的数组,与容器中任何其他数组的类型无关:
单元格数组:array{i,j}
struct array:array(i,j).value
标量结构:array.value
所以这一切都取决于你想要索引的方式:
array(i,j).value
^ ^
A B
如果您只想使用A
进行索引,请使用单元格数组(当然,您需要花括号)。如果只想使用B
进行索引,请使用标量结构。如果您同时需要A
和B
,请使用结构数组。
我所知道的成本没有差别。这些容器中包含的每个数组占用一些空间。各种容器的空间开销是相似的,我从未注意到时间间隔的差异。
然而,这两者之间存在巨大差异:
array(i).value % s1
array.value(i) % s2
我认为这个问题也解决了这个问题。 s1
的空间开销大于s2
:
>> s1=struct('value',num2cell(1:100))
s1 =
1×100 struct array with fields:
value
>> s2=struct('value',1:100)
s2 =
struct with fields:
value: [1×100 double]
>> whos
Name Size Bytes Class Attributes
s1 1x100 12064 struct
s2 1x1 976 struct
数据需要800个字节,因此s2
有176个字节的开销,而s1
有11264个(1408%)!
原因不是容器,而是我们将一个包含100个元素的数组存储在一个数组中,而将100个数组存储在另一个数组中。每个数组都有一个特定大小的标题,MATLAB用它来知道它是什么类型的数组,它有多大的尺寸,管理它的存储和延迟复制机制。拥有的数组越少,使用的内存就越少。
所以,不要使用异构容器来存储标量!这些只在你需要存储更大的数组或不同类型或大小的数组时才有意义。
未明确询问的异构容器(以及明确未询问的编辑后)是表。表类似于标量结构,表的每一列都是单个数组,不同的列可以有不同的类型。请注意,可以将单元格数组用作列,允许将异构元素存储在列中,但如果不是这样,它们最有意义。
标量结构的一个区别是每列必须具有相同的行数。另一个区别是索引可能看起来像单元格数组,标量结构或结构数组。
因此,该表强制对所包含的数据施加一些约束,这在某些情况下非常有用。
然而,正如OP所指出的,使用表格比使用结构表更慢。这是因为table
是一个自定义类,而不是像结构和单元数组这样的本机类型。如果您在MATLAB中键入edit table
,您将看到源代码,以及它是如何实现的。它是一个classdef
文件,就像我们任何人都可以写的一样。因此,它具有相同的速度限制:JIT没有针对它进行优化,索引到表意味着运行写为M文件的函数等。
还有一件事:不要创建结构的单元格数组,或者使用单元格数组创建标量结构。这增加了容器的容量,这增加了开销(空间和时间),并且使得内容更难以使用。我在这里看到了与此类构造引起的与访问数据的难度相关的问题:
data{i,j}.value % A cell array with structs. Don't do this!
data.value{i,j} % A struct with cell arrays. Don't do this!
第一个示例等于struct数组(具有更多开销),除了无法控制每个单元格中的struct字段。也就是说,其中一个单元格可能没有.value
字段。
仅当value
与第二个struct字段的大小不同时,第二个示例才有意义。如果所有结构域都是(应该是)具有相同大小的单元数组,那么使用结构数组。同样,更少的开销和更多的一致性。