宁用循环也不要用这几个matlab函数

2023-03-17 12:59:54 浏览数 (2)

正如引言中所讲,并不是所有的matlab矢量化函数对程序运行效率都是提高的,有时候该用循环还是要乖乖用循环,不能一味地追求矢量化。

今天小编通过实例给大家展示所谓的向量化函数与for循环之间的运行效率对比(注:这里的效率指的是完成同样的工作所花时间的多少,所花时间越少效率越高,反之越低)。

这几个函数依次为:arrayfun、cellfun、structfun、spfun

相信有不少小伙伴在日常编程中常用到前三个,最后一个接触得相对较少,平时也是只管使用,没有注意到程序运行效率。下面就与小编一起来巴拉巴拉这几个函数,希望能对大家有所启发,俗话讲尽信书则不如无书。

一、arrayfun函数

函数功能:将函数应用于数组的每个元素

与for循环效率对比:

代码语言:javascript复制
M = 4000;
N = 500;
x = randn(M, N);

tic
T1 = ones(M, N);
for m = 1:M
    for n = 1:N
        T1(m, n) = fun(x(m,n));
    end
end
tfor = toc

tic
T2 = arrayfun(@fun, x);
tarr = toc
代码语言:javascript复制
% fun函数
function y = fun(x)
y = 0.5*x.^2   cos(x) - 1;

在小编电脑上运行结果为:tfor=0.1713;tarr=3.5196,for循环arrayfun快20倍左右(注:运行结果和电脑硬件有关)。

二、cellfun函数

函数功能:将函数应用于元胞数组的每个元胞

与for循环效率对比:

代码语言:javascript复制
A = num2cell(rand(1000));
% for测试
tic;
for m = 1:500
    for n = 1:500
        A{m,n} = fun(A{m,n});
    end
end
tfor = toc

% cellfun测试
tic;
A = cellfun(@fun,A,'UniformOutput', false);
tcel = toc

在小编电脑上运行结果为:tfor=0.1164;tarr=2.1745,for循环cellfun快18倍左右(注:运行结果和电脑硬件有关)。

三、structfun函数

函数功能:将函数应用于标量结构的每个字段

与for循环效率对比:

代码语言:javascript复制
clc;clear;
data.x = linspace(0,2*pi,10000);
data.y = sin(data.x);
tic;
for k = 1:10000
    data.x(k) = fun(data.x(k));
    data.y(k) = fun(data.y(k));
end
tfor = toc

tic 
data = structfun(@fun,data,'UniformOutput',false);
tstr = toc

在小编电脑上运行结果为:tfor=0.0118;tstr=5.1300e-04,structfunfor循环快22倍左右(注:运行结果和电脑硬件有关)。

四、spfun函数

函数功能:将函数应用于非零稀疏矩阵元素

与for循环效率对比:

代码语言:javascript复制
load('west0479.mat');
tic;
[linesF, columnsF, valuesF] = find(west0479);
len = length(valuesF);
for k = 1:len
    valuesF(k) = fun(valuesF(k));
end
Q = sparse(linesF, columnsF, valuesF);
tfor = toc

tic 
Q = spfun(@fun,west0479);
tsp = toc

在小编电脑上运行结果为:tfor=0.0015;tsp=4.0190e-04,spfunfor循环快3倍左右(注:运行结果和电脑硬件有关)。

通过上面示例对比不难发现,arrayfuncellfun目前的运行效率是低于同等情况下的for循环structfun的运行效率要高于同等情况下的for循环,而spfunfor循环的差异不太大,因此也建议大家程序中少用arrayfun与cellfun,至少现在的版本要少用。

从上面的示例也不难看出,不能迷信所谓的矢量化计算,还得结合自身需要进行合理选择才能写出高效运行的代码。

参考资料:

[1] https://stackoverflow.com/questions/16143314/matlab-arrayfun-cellfun-spfun-and-structfun-vs-simple-for-loop

[2] https://stackoverflow.com/questions/12522888/arrayfun-can-be-significantly-slower-than-an-explicit-loop-in-matlab-why

[3] https://stackoverflow.com/questions/15851718/what-is-the-fastest-way-to-perform-arithmetic-operations-on-each-element-of-a-ce

[4] https://groups.google.com/forum/#!topic/comp.soft-sys.matlab/DCGTm-BhGIE

[5] https://ww2.mathworks.cn/help/matlab/ref/arrayfun.html

[6] https://ww2.mathworks.cn/help/matlab/ref/cellfun.html

[7] https://ww2.mathworks.cn/help/matlab/ref/structfun.html

[8] https://ww2.mathworks.cn/help/matlab/ref/spfun.html

如需转载,请在公众号中回复“转载”获取授权,未经授权擅自搬运抄袭的,必将追究其责任!

0 人点赞