Improving speed in while loop
11 views (last 30 days)
Show older comments
This is a quite specific example, but any help is welcome.
I have a motorized pan-tilt system with the corresponding Matlab functions to make it move to a set position and read out the Azimuth & Elevation at any time. I'm having the system swivel from left to right and back and forth for 2 minutes, and need to register its rotation as often as possible. Currently, it manages ~17 positions per second, but I'm hoping to reach 50 (~20ms/loop).
Below you can find the code, but the general setup within the while loop is as follows:
- Check current time
- Get current position
- Write time & position to new line in an open file.
- Check whether current position is at earlier defined limit, if yes, start moving in the opposite direction.
- Repeat.
Note that ultimately I want to do runs of up to 2 hours, and to prevent data loss in case of an error I start a new "position log file" every minute. The target computer doesn't have matlab, but runs a compiled version of this code with the required runtime.
Can this code be made any faster, assuming the Pan-Tilt functions have been optimized? I think the slowest part is in the fprintf, but I'm not sure how to reduce the load here.
Any help is welcome, thanks!
% Move back and forth between two limit positions.
TS(1,:) = clock; %TS = TimeStamp
tic
timelimit = toc;
while timelimit<125 % Run for slightly over 2 minutes
timelimit = toc;
% Get position
[pan,tilt]=GetPos(SSS,obj1);
% Save position in Log File
% Prepare data for input
TS(2,:) = clock; %TimeStamp
data = [TS(2,:) pan tilt PanSpeed TiltSpeed]; %Time, panposition, tiltposition, panspeed, tiltspeed
% Check: Has a minute passed? If no, just write data. If yes, close file and start new one.
if TS(2,5) == TS(1,5) % Check if still same minute
% Add line with filename & data
fprintf(fileID,FormatSpec,data);
else
fclose(fileID);
filename = sprintf('%02d_%02d',TS(2,4),TS(2,5)); % Filename has hours and minutes, with leading 0 if necessary.
fileID = fopen(fullfile(LogPath,strcat(filename,'.txt')),'wt');
fprintf(fileID,FormatSpec,data);
end
TS(1,:) = TS(2,:);
% Check whether left or right limit has been reached.
if abs(pan-PanLimRight) < 500 && GoRight == 1
IsRight = 1;
elseif abs(pan-PanLimLeft) < 500 && GoLeft == 1
IsLeft = 1;
end
if IsLeft == 1 && GoLeft == 1 % If left limit has been reached (while moving left)
%Move right
StopMotion(SSS,obj1);
GoToPosRate_NW(SSS,PanSpeed,PanLimRight,TiltSpeed,TiltLimRight,MMM,obj1);
GoLeft = 0;
GoRight = 1;
IsLeft = 0;
end
if IsRight == 1 && GoRight == 1 %If right limit has been reached (while moving right)
% Move left
StopMotion(SSS,obj1);
GoToPosRate_NW(SSS,PanSpeed,PanLimLeft,TiltSpeed,TiltLimLeft,MMM,obj1);
GoLeft = 1;
GoRight = 0;
IsRight = 0;
end
end
1 Comment
Adam
on 24 Jan 2018
"I think the slowest part is in the fprintf"
Never do optimisation work based on 'I think'. The Matlab profiler is excellent and trivially simple to use compared to profilers for languages like C++ (at least last time I used a C++ profiler).
doc profile
will give you details and you can be finding all the information you need about which parts are slow in no time at all. It won't tell you how to speed them up of course, but there's nothing worse when optimising code than just making assumptions and putting a lot of effort into speeding up something that actually only takes 2% of the total time anyway so that even an amazing speedup in that component will only ever make your code < 2% faster.
Accepted Answer
Jan
on 23 Jan 2018
I'd change the fopen('wt') to fopen('W') (upper-case W for buffering), but I do not assume that this changes the runtime remarkably.
if IsLeft && GoLeft might be slightly faster, but again, that change is minimal.
The posted code does not contain obvious slow commands. Maybe collecting the data in the RAM is faster than writing to the disk. Especially if this is a real-time approach, an automatic start of the disk fragmentation would let the system fail.
But the actual time consuming parts would be revealed by the profiler: Run it and check, where the most time is used. I guess, that it is GetPos(), StopMotion() and GoToPosRate_NW(). Then the shown code cannot influence the total run time substantially. Remember that accelerating a piece of code by (impossible) 100% will accelerate the total code by 1% only, , if it uses 1% of the total time only. So focus on the bottlenecks only: Use the profiler to find, where time can be saved at all.
More Answers (0)
See Also
Categories
Find more on Loops and Conditional Statements in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!