使用匿名函数优化MATLAB代码性能的瓶颈

7
我在Matlab 2011a中使用匿名函数遇到了严重的性能问题,其中匿名容器函数引入的开销远大于所包含函数本身所需的时间。
我读了一些相关的问题,用户们都很热心地解释说这是其他人也经历过的问题,他们表明如果不使用匿名容器,我可以通过这种方式显著提高性能。不幸的是,我的代码结构使我不确定如何在不破坏很多东西的情况下做到这一点。
因此,有没有方法来改善匿名函数的性能,而不完全放弃它们,或者有没有设计模式可以让我放弃它们而不会膨胀我的代码并花费大量时间进行重构?
以下是匿名函数的集合,它们被存储为类属性。原则上,可以使用一个整数数组来替换数组,该数组反过来由switch语句使用,但GPs的内容可能会发生变化--还有其他具有与traingps相同参数结构的函数可以在那里使用--而且GPs的内容在某些情况下可能是在运行时确定的。
m3.GPs = {@(X,ytrain,xStar,noisevar,params)traingp(X,ytrain,xStar,noisevar,1,params,[1  0]');
       @(X,ytrain,xStar,noisevar,params)traingp(X,ytrain,xStar,noisevar,1,params,[-1 1]');
       @(X,ytrain,xStar,noisevar,params)traingp(X,ytrain,xStar,noisevar,2,params,0);
       @(X,ytrain,xStar,noisevar,params)traingp(X,ytrain,xStar,noisevar,3,params,0);
       @(X,ytrain,xStar,noisevar,params)traingp(X,ytrain,xStar,noisevar,4,params,[0 0 0]')};

稍后,GP的元素将通过类的成员函数进行调用,如下所示:
GPt = GPs{t(j)}(xj,yj,gridX(xi),thetaT(1),thetaT(2:end));

根据分析工具,匿名包装器的自我时间占总时间的95%(44次调用需要1.7秒!),而所包含函数的时间仅占5%。我在其他地方使用了类似的方法,其中匿名包装器的成本甚至更高,按比例算。

请问有没有任何想法可以减少匿名调用的开销?如果不行,有没有办法在保留它们提供的灵活性的同时替换匿名函数(而不引入大量的额外记录和参数传递)?

谢谢!


1
为什么不将整数和数组添加到参数中呢?我认为通过避免使用函数数组,而是使用一个将该数组的索引作为参数的函数,可以大大简化这个问题。 - stardt
@ChrisLucas:你能提供一个我们可以自己测试的最小工作示例吗? - Amro
@stardt:不幸的是,我真的想保留泛化到其他具有相同参数结构的未知函数可以替换给定函数的情况的能力,可能在运行时。如果有一种方法可以在消除函数数组的同时实现这一点,我很乐意尝试一下。 - Chris
@amro:我很快就会尝试做这件事,在我从会议回来后。相关的代码不容易提取,但似乎它会很有价值。 - Chris
@ChrisLucas 我已经发布了一种改变函数参数结构的方法,虽然这并没有真正回答你的问题。 - stardt
2个回答

1

最终问题在于你愿意承受多少痛苦来提高性能。这里有一个避免使用匿名函数的技巧。我不知道它在你的分析中表现如何。我相信你可以将这些“微小”的函数放在类文件的末尾(我知道你可以将它们放在常规函数文件的末尾)。

function [output] = GP1(x,ytrain,xstar,noisevar,params)
   output = traingp(X,ytrain,xStar,noisevar,1,params,[1  0]);
end
...

m3.GPS = {@GP1, @GP2, ...}; 

1
也许一个“工厂”函数会有所帮助:
>> factory = @(a,b,c) @(x,y,z) a*x+b*y+c*z;
>> f1 = factory(1,2,3);
>> f2 = factory(0,1,2);
>> f1(1,2,3)
ans =
    14
>> f1(4,5,6)
ans =
    32
>> f2(1,2,3)
ans =
     8
>> f2(4,5,6)
ans =
    17

在这里,factory是一个返回具有不同参数的新函数的函数。另一个例子可能是:
 factory = @(a,b,c) @(x,y,z) some_function(x,y,z,a,b,c)

返回一个函数,该函数使用指定的 a,b,c 和变量 x,y,z


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接