Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

improving performance of matlab code with anonymous-function bottlenecks

I'm running into serious performance issues with anonymous functions in matlab 2011a, where the overhead introduced by an anonymous container function is far greater than the time taken by the enclosed function itself.

I've read a couple of related questions in which users have helpfully explained that this is a problem that others experience, showing that I could increase performance dramatically by doing away with the anonymous containers. Unfortunately, my code is structured in such a way that I'm not sure how to do that without breaking a lot of things.

So, are there workarounds to improve performance of anonymous functions without doing away with them entirely, or design patterns that would allow me to do away with them without bloating my code and spending a lot of time refactoring?

Some details that might help:

Below is the collection of anonymous functions, which are stored as a class property. Using an int array which is in turn used by a switch statement could replace the array in principle, but the content of GPs is subject to change -- there are other functions with the same argument structure as traingps that could be used there -- and GPs' contents may in some cases be determined at runtime.

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]')};

Later, elements of GPs are called by a member function of the class, like so:

GPt = GPs{t(j)}(xj,yj,gridX(xi),thetaT(1),thetaT(2:end));

According to the profiler, the self-time for the anonymous wrapper takes 95% of the total time (1.7 seconds for 44 calls!), versus 5% for the contained function. I'm using a similar approach elsewhere, where the anonymous wrapper's cost is even greater, proportionally speaking.

Does anyone have any thoughts on how to reduce the overhead of the anonymous calls, or, absent that, how to replace the anonymous function while retaining the flexibility they provide (and not introducing a bunch of additional bookkeeping and argument passing)?

Thanks!

like image 726
Chris Avatar asked Oct 28 '11 16:10

Chris


2 Answers

It all comes down to how much pain are you willing to endure to improve performance. Here's one trick that avoids anonymous functions. I don't know how it will profile for you. You can put these "tiny" functions at end of class files I believe (I know you can put them at the end of regular function files.)

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

m3.GPS = {@GP1, @GP2, ...}; 
like image 170
John Avatar answered Oct 07 '22 21:10

John


Perhaps a function "factory" would help:

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

Here, factory is a function that return a new function with different arguments. Another example could be:

 factory = @(a,b,c) @(x,y,z) some_function(x,y,z,a,b,c)

which returns a function of x,y,z with a,b,c specified.

like image 23
stardt Avatar answered Oct 07 '22 23:10

stardt