最近遇到了这个问题,注意到虽然 Octave 在 cellfun 中有隐式的单元格扩展参数,但 Matlab 没有。调用匿名函数比直接调用函数的开销更大(尽管在这方面 Matlab 不如 Octave 差),所以我发现将参数作为单元数组传递会更快一些,这里用一个简单的例子展示:
abc = {magic(2), magic(3), magic(4)}
abc =
3×1 cell array
{2×2 double}
{3×3 double}
{4×4 double}
def = cellfun (@(x) sum(x,2), abc, "UniformOutput", false) %anonymous function method
def =
3×1 cell array
{2×1 double}
{3×1 double}
{4×1 double}
def{:}
ans =
4
6
ans =
15
15
15
ans =
34
34
34
34
将参数扩展为元胞数组并将其作为另一个输入传递会产生相同的正确输出:
def = cellfun (@sum, abc, num2cell(2*ones(size(abc))), "UniformOutput", false) % cell expansion method
def =
3×1 cell array
{2×1 double}
{3×1 double}
{4×1 double}
def{:}
ans =
4
6
ans =
15
15
15
ans =
34
34
34
34
快速 tic/toc 检查表明这在 Matlab 2021a 中要快一些:
tic;
for idx = 1:100000
cellfun(@(x) sum(x,2), abc,"UniformOutput",false);
end
toc
Elapsed time is 4.017116 seconds.
tic,
for idx = 1:100000
cellfun(@sum, abc, num2cell(2*ones(size(abc))),"UniformOutput",false);
end
toc
Elapsed time is 1.217712 seconds
我没有尝试过使用非简单参数,但 repmat 可以为字符串输入做同样的事情,但 repmat 似乎增加了相当多的开销:
tic
for idx = 1:100000
cellfun(@sum, abc, repmat({2}, size(abc)),"UniformOutput",false);
end
toc
Elapsed time is 4.367002 seconds.
所以也许有更好的方法来扩展这些。请注意,这是一个非常简单的带有小数组的测试用例,并且随着事情的扩大或添加多个参数,这种时间节省可能不会成立。此外,您正在乘以执行此操作的每个参数的内存需求,因为每个参数都扩展为输入数组的大小。
快速测试表明,使用自定义 myfunc 与使用 sum 等 matlab 函数可以节省相同的时间。