Why are the 2 lines at the end so time consuming?

1 visualizzazione (ultimi 30 giorni)
Hi, I just ran the profiler on a function and was quite surprised.
EDIT: New run
function outputVector = addAndReplace(inputVector,addVector,atElement,addValue)
0.25 10000 18 if not(exist('addValue','var'))
19 addValue = 0;
20 end
21
0.01 10000 22 if isscalar(atElement)
23 atElement = [atElement,atElement];
24 end
25
< 0.01 10000 26 len = length(inputVector)+length(addVector)-1-(atElement(2)-atElement(1));
0.03 10000 27 sizeVector = size(inputVector);
< 0.01 10000 28 if sizeVector(1) > 1;
29 outputVector = zeros(len,1);
< 0.01 10000 30 else
2.28 10000 31 outputVector = zeros(1,len);
< 0.01 10000 32 end
0.15 10000 33 outputVector(1:atElement(1)-1) = inputVector(1:atElement(1)-1);
0.07 10000 34 outputVector(atElement(1):atElement(1)+length(addVector)-1) = addVector;
12.55 10000 35 outputVector(atElement(1)+length(addVector):end) = inputVector(atElement(2)+1:end)+addValue;
The function was created to replace elements between adElement(1) and adElement(2) (start and end index) with the vector addVector. and if necessary, add a value addValue to the last elements. This to save myself some headache while creating and debugging the code.
Is there anyone who knows why the final lines takes much more time to execute than creating an empty matrix? I have heard something about matlab creates one pointer and copies it for every element when creating a zeros matrix, can this be the reason why line 30 is faster?
BR/ Patrik
  8 Commenti
Niklas Nylén
Niklas Nylén il 18 Mar 2014
I do not have an answer, but interestingly row 34 is very quick for me (0.15 s) while row 36 is very time consuming (7.98 s). Could it be a difference in the input data or will different Matlab versions/OS's handle the code differently?
Patrik Ek
Patrik Ek il 18 Mar 2014
@Niklas Nylén, sorry I take the blame for this one. The question was old and the original run was lost in time. I edit so that the example is updated.

Accedi per commentare.

Risposta accettata

Matt J
Matt J il 18 Mar 2014
Modificato: Matt J il 18 Mar 2014
SUBSREF operations are costly. Because you are extracting data from inputVector, memory allocation is required. A whole new vector gets allocated/created to hold extracted data such as
inputVector(atElement(2)+1:end)
and
inputVector(1:atElement(1)-1)
  2 Commenti
Patrik Ek
Patrik Ek il 18 Mar 2014
Thanks for that! Now if you have time for a following question, is there a solution to that? I will still accept the answer right now by the way.
Matt J
Matt J il 18 Mar 2014
Depends on what is really changing throughout the loop. In your example, nothing is.

Accedi per commentare.

Più risposte (2)

per isakson
per isakson il 18 Mar 2014
Modificato: per isakson il 18 Mar 2014
I run your example on R2013a 64bit, Win7, and and old vanilla desktop. Our line number differs. You stripped off 18 lines in the beginning of the function?
Comments
  • obsolete it is remarkable that my line 18 (your 34) in my case use very little time.
  • obsolete my line 16 use much more time than your corresponding line.
  • have you tried to use Windows The Task Manager to see if copies of the vector are created?
  • I'm not surprised that manipulating arrays takes time
The working of the Matlab acceletator is a secret of The Mathworks. However, see Array resizing performance and Internal Matlab memory optimizations at Undocumented Matlab. And there was a post on performance and "In-place Operations on Data" at Loren on the Art of MATLAB. (At the moment it says error 404)
2.07 10000 16 outputVector = zeros(1,len);
0.01 10000 17 end
0.18 10000 18 outputVector(1:atElement(1)-1) = inputVector(1:atElement(1)-1);
0.03 10000 19 outputVector(atElement(1):atElement(1)+length(addVector)-1) = addVector;
13.37 10000 20 outputVector(atElement(1)+length(addVector):end) ...
21 = inputVector(atElement(2)+1:end)+addValue;
0.35 10000 22 end
  1 Commento
Patrik Ek
Patrik Ek il 18 Mar 2014
Modificato: Patrik Ek il 18 Mar 2014
Sorry about the times, see edit. And regarding the missing lines I stripped of the help part to keep the amount of text down in the question.

Accedi per commentare.


Sara
Sara il 18 Mar 2014
I don't know why it's slow on those line, but since you know the pieces of the final array, instead of calculating its dimension, you can do:
p1 = inputVector(1:atElement(1)-1);
p2 = addVector;
p3 = inputVector(atElement(2)+1:end)+addValue;
if(size(inputVector,1) == 1)
outputVector = [p1,p2,p3];
else
outputVector = [p1;p2;p3];
end
It's faster than your code and it does the same thing.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by