Slow Anonymous Function

Suppose you have a loop with 50,000 iterations and you want to calculate averages (scalars) from many matrices. This is not complete, but something like this:

for k=1:50000 ... mean=sum(sum(matrix))/numel(matrix); %Arithmetic mean ... end 

And now I want to include various mean equations to choose from. First I tried this:

 average='arithmetic' for k=1:50000 ... switch average case 'arithmetic' mean=sum(sum(matrix))/numel(matrix); %Arithmetic mean case 'geometric' mean=prod(prod(matrix)).^(1/numel(matrix)); %Geometric mean case 'harmonic' mean=numel(matrix)/sum(sum(1./matrix)); %Harmonic mean end ... end 

This is obviously much slower than the first loop, because it needs to find a matching string for each iteration, which seems completely unnecessary. Then I tried this:

 average='arithmetic' switch average case 'arithmetic' eq=@ (arg)sum(sum(arg))/numel(arg); %Arithmetic mean case 'geometric' eq=@ (arg)prod(prod(arg)).^(1/numel(arg)); %Geometric mean case 'harmonic' eq=@ (arg)numel(arg)/sum(sum(1./arg)); %Harmonic mean end for k=1:50000 ... mean=eq(matrix); %Call mean equation ... end 

This is about twice as slow as the first cycle, and I don’t understand why. The last two cycles are almost identical in speed.

Am I doing something wrong here? How can I achieve the same performance as the first loop with this extra feature?

Help is much appreciated!

+6
source share
2 answers

Having a switch inside the loop performs a comparison of 50,000 times, which needs to be done only once, which I would recommend.

The second is a little more subtle, but it is likely that the eq function is dynamically scanned at each iteration and possibly interpreted each time (not sure how MATLAB does the optimization). Your best bet for performance is probably to include a for loop inside the switch.

 switch average case 'arithmetic' for ... end case 'geometric' for ... end case 'harmonic' for ... end end 
+5
source

It’s good that every function, even anonymous functions , can have a certain amount of additional overhead associated with calling it, making them a little slower than their single-line expressions in your example. However, in this case, there may be additional overhead because functions by the name eq already exist in abundance in MATLAB, since eq is the name of the method of the overloaded operator == . Using the WHICH command:

 >> which eq -all 

It will show you that eq very overloaded, and one of them exists for each of the main data types and most objects.

I would try using a different name for your anonymous function descriptor to see if the dispatcher can be a factor, although I doubt that it is based on a priority order function (i.e. variables always take precedence). The best solution to solve the problem may be to avoid unnecessary overhead of functions by doing something like DavW .

I would like to make another suggestion. Many of the mathematical operations you do can be greatly improved to make them more efficient, in particular using the MEAN function and the colon operator to change the entire matrix to a column vector:

 result = mean(matrix(:)); %# For the arithmetic mean result = prod(matrix(:))^(1/numel(matrix)); %# For the geometric mean result = 1/mean(1./matrix(:)); %# For the harmonic mean 

Note that I did not use the mean name for my variable, as this is already used for the inline function , and you definitely do not want to obscure it.

+5
source

Source: https://habr.com/ru/post/885996/


All Articles