与每个字段的单个元胞数组相比,MATLAB 结构元胞数组非常慢
MATLAB cell array of structs very slow compared to individual cell arrays for each field
我有一些代码,其中有特定的 class 个对象,每个对象都有多个字段。从面向对象的角度来看,它是您所能得到的 classic。
我初始化代码为:
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)
这样的子集时),但我显然不想承受计算量。这里的正确选择是什么?
更好的是,有没有隐藏的、更好的第三种选择?
您被误导了,因为在您最初的方法中,您需要 元胞数组以便在每个 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
并根据需要填写每个字段。
我有一些代码,其中有特定的 class 个对象,每个对象都有多个字段。从面向对象的角度来看,它是您所能得到的 classic。
我初始化代码为:
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)
这样的子集时),但我显然不想承受计算量。这里的正确选择是什么?
更好的是,有没有隐藏的、更好的第三种选择?
您被误导了,因为在您最初的方法中,您需要 元胞数组以便在每个 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
并根据需要填写每个字段。