我能想到几个方法。首先,我通过生成一些虚假数据
A = cellfun(@(~)rand(2,1), cell(1000), 'uni', false);
B = rand(2);
细胞乐趣
正如您所说,这是您要避免的。在任何情况下,我都会将其包含在此处进行比较:
C = cellfun(@(x)B*x, A, 'UniformOutput',false);
由于涉及匿名函数,它很慢。带有内置字符串函数(请参阅 参考资料help cellfun
)的 Cellfun 正在迅速发展,但是,匿名函数会在每次迭代时强制执行由 Matlab 解释器通过。尽管 JIT 可以在一定程度上提高效率,但远非最佳。
单元格扩展,num2cell,重塑
想法:将单元格扩展为 2x1000 矩阵,执行乘法,然后将结果转换回正确大小的单元格数组。虽然原则上很优雅,但在实践中它变得有点混乱:
C = reshape( num2cell(B*[A{:}],1), size(A) );
请注意,从内存占用的角度来看,中间的 2x1000 临时文件有点浪费……而且,通过num2cell
(非内置)和“无用”reshape
会大大减慢执行速度。
循环
循环最容易阅读,最容易实现。内存占用小,有利于 JIT 加速等。
C = cell(size(A));
for ii = 1:numel(A)
C{ii} = B*A{ii};
end
唯一的缺点是它的坏名声:)
比较
现在是踢球者:哪一个是最快的?
tic
C = cellfun(@(x)B*x, A, 'uni',false);
toc
tic
C = reshape( num2cell(B*[A{:}],1), size(A) );
toc
tic
C = cell(size(A));
for ii = 1:numel(A)
C{ii} = B*A{ii};
end
toc
结果:
Elapsed time is 4.738791 seconds. % cellfun
Elapsed time is 4.161515 seconds. % cell expansion, num2cell, reshape
Elapsed time is 3.808822 seconds. % loop
结论:自 R2008 引入 JIT 编译以来,循环不再是邪恶的;默认情况下不要试图避免它们。