【问题标题】:MATLAB cell array of structs very slow compared to individual cell arrays for each field与每个字段的单个元胞数组相比,结构的 MATLAB 元胞数组非常慢
【发布时间】:2015-07-27 00:49:03
【问题描述】:

我有一些代码,其中有特定类别的对象,每个对象都有许多字段。从面向对象的角度来看,它几乎是您所能获得的经典。

我将代码初始化为:

object = cell(N, 1);
% Each field may contain matrices of different dimensions at each iteration
for i = 1 : N
    object{i}.field1 = ones(1000, 3);
    object{i}.field2 = imread('some_image.png');
    object{i}.field3 = (1:.002: 4);
    object{i}.field4 = im > 0;
    ...
    % And so on for more large matrices and such
end

我之前将其编码为:

field1 = cell(N, 1);
field2 = cell(N, 1);
field3 = cell(N, 1);
field4 = cell(N, 1);
....
for i = 1 : N
    field1{i} = ones(1000, 3);
    field2{i} = imread('some_image.png');
    field3{i} = (1:.002: 4);
    field4{i} = im > 0;
    ...
    % And so on for more large matrices and such
end

然后我继续以各种方式操作与每个对象中的每个字段关联的值。第二种方法的运行速度比第一种快约 4 倍。效率低下肯定是由于这种二元性。我更改的唯一代码是从多个单元格数组切换到一个结构数组的单元格。 我知道结构数组以速度较慢而著称,但我也看到建议将结构传递给函数。我在这里错过了什么?

我真的很喜欢结构单元数组的编码简洁性(特别是当您想要获取像 subset = object(1:4) 这样的子集时),但我显然不想受到计算上的影响。这里的正确选择是什么?

更好的是,是否有隐藏的、更好的第三个选项?

【问题讨论】:

  • 在第一个示例中,您甚至不需要使用单元格。您正在动态更新object 元胞数组的字段和 大小。尝试像这样初始化object:object = struct('field1', cell(N,1), 'field2', cell(N,1), 'field3', cell(N,1), 'field4', cell(N,1)),然后填写值。除此之外,您可能需要包含更多代码/信息以推断导致速度变慢的原因。
  • @jucestain:我确实需要细胞。我想我在概括我的代码时错过了这一点,但我现在编辑了它。每个对象都包含不同大小的图像等。因此,虽然这个可能有 1100x1200 矩阵,但下一个可能有 980x740,依此类推。另外,我已经预先分配了对象数组,但你是对的——这些字段没有预先分配。我认为在第一次迭代之后,这些字段将全部分配。
  • 第一个示例中不需要单元格。使用我的建议,您可以执行object(1).field1 = ones(10,1) 和object(2).field1 = ones(10,10),这很好。在第二个示例中,您只需要单元格。
  • @jucestain:啊,你说的只是一个标准的结构数组......明白了
  • 第二部分的编写方式是动态扩展object 单元格数组,并在每次迭代时动态创建一个新结构。如果您在object 的每个索引中包含不同的结构,您只需要这样做。按照您的编码方式,object 中的每个索引都应该具有相同的结构(具有相同的字段),因此您可以按照您的建议预先分配它并将其用作结构数组,而不是单元格数组。跨度>

标签: matlab struct cell-array


【解决方案1】:

您误入歧途,因为在您最初的方法中,您需要元胞数组以便在每个field* 索引中容纳不同大小的数组。

但是,当您决定在第二种方法(更好的方法)中使用结构时,您实际上并不需要使用元胞数组。因此,如果您检查此代码段:

for i = 1 : N
    object{i}.field1 = ones(1000, 3);
    object{i}.field2 = imread('some_image.png');
    object{i}.field3 = (1:.002: 4);
    object{i}.field4 = im > 0;
    ...
    % And so on for more large matrices and such
end

这里实际发生的是在每次迭代中,它在每次迭代中动态形成一个结构。不仅如此,每次您添加一个新字段时,它也会动态地将一个新字段添加到该结构中。仅当您在元胞数组的每个索引中容纳 不同 结构时,才需要这样做。

但是,由于您在每个索引中使用相同的结构,您可以简单地使用结构数组。您可以使用以下方法预先分配整个事物:

object = struct('field1', cell(N,1), 'field2', cell(N,1), ...);

然后遍历object 并根据需要填写每个字段。

【讨论】:

    猜你喜欢
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多