Why are the 2 lines at the end so time consuming?
1 view (last 30 days)
Show older comments
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 Comments
Niklas Nylén
on 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?
Accepted Answer
Matt J
on 18 Mar 2014
Edited: Matt J
on 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 Comments
Matt J
on 18 Mar 2014
Depends on what is really changing throughout the loop. In your example, nothing is.
More Answers (2)
per isakson
on 18 Mar 2014
Edited: per isakson
on 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
Sara
on 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.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!