避免跨函数传递大型数组

时间:2015-05-28 17:30:21

标签: arrays matlab function

考虑以下最小测试问题

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包。

1 个答案:

答案 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

干杯