考虑以下最小测试问题
function [P1,P2,P3] = test()
D = 20;
paths = 1e6;
P1 = zeros(1,paths); P2 = zeros(1,paths); P3 = zeros(1,paths);
G = @(x,flag) A(x,flag);
tic
for i = 1:paths
X = randn(1,100);
P1(i) = G(X,1);
end
t1 = toc;
tic
for i = 1:paths
X = 2*randn(1,100);
P2(i) = G(X,1);
end
t2 = toc;
tic
a = function(@(x) A(x,0));
for i = 1:paths
X = a*randn(1,100);
P3(i) = G(X,1);
end
t1 = toc;
function [A] = A(x,flag)
A = sum(x);
if flag==1
A = A/length(x);
end
function [B] = B(x,flag)
B = 0;
for 1:length(x)
B = (-1)^i * x(i);
if flag==1
B = B/length(x);
end
因此它是一个在某些不同数据上运行函数A或函数B的函数。但是我的问题是每次我调用函数A或函数B时我都会传递一个相对较大的数组(它可能大于1x100,我只选择了一个数字)并且我做了很多次。请注意,我确实需要函数A和B作为我在函数调用中需要它们的函数(这里简称为“函数”),你可以使用你喜欢的任何东西,这不是有趣的部分。
现在明显的问题是,如何加快速度?
一个简单的方法是简单地将函数A和函数B硬编码到每个for循环中(在某种意义上我将代码复制到for循环并避免函数句柄)并使用一些if语句来决定哪一个,然后我不必多次传递矩阵。但首先,这是非常丑陋的,实际上我有比A和B更多的功能。
我想到的另一种方法是制作多个功能,每个功能一个,但是由于我有许多功能,它很快变得丑陋,我想保持在开始时必须改变感兴趣的功能的美感。 / p>
那么有没有什么方法可以让它变得更快,但仍然保持只需要改变一次感兴趣的功能的美感和容易度? 我当然会并行化for循环,但它并没有真正解决实际问题。
我有所有matlab包。
答案 0 :(得分:1)
我很抱歉,但直接方法是最快的方法。在进行1e6次呼叫时,结果是一致的。我已经排除了每个周期的randn
来电:
根本不使用任何功能
无功能直接呼叫:20.38742秒(1e7呼叫)
使用标准功能
标准函数调用:24.26631秒(1e7调用)
使用匿名句柄
匿名函数调用:38.76371秒(1e7调用)
使用类作为句柄
Class as Handle:211.4325 sec(1e7 calls)
越简单越好......
PS。不要怪我的机器。它只是,有效...
修改强>
请注意,如果您需要传递一个函数作为参数,您可以使用以下任何一个 - 包括但不限于 - 以下选项,所有这些选项都可以被称为G(x,flag)
,并且所有这些选项都可以要求拥有"命名"功能范围:
% Option 1
varfun=@(x,flag) A(x,flag);
G=varfun;
% Option 2
strfun='A(x,flag)';
eval(sprintf('G=@(x,flag) %s;',strfun));
% Option 3
namefun='A';
G=str2func(namefun);
% Option 4
strfun='A(x,flag)';
G=inline(strfun,'x','flag');
% Option 5
keyfun='A';
switch keyfun
case 'A'
G=@(x,flag) A(x,flag);
case 'B'
G=@(x,flag) B(x,flag);
end
干杯