pause function gives inconsistent timing when used inside a loop.
Show older comments
Hello,
I am trying to create an animated plot. The pause command inside an infinite loop is supposed to created the timing for me:
%%
figure; clf;
t = 0:1/16000:1;
y = sin(2*pi*4*t);
h = plot(t,y);
xlim([ 0 t(end)]);
ylim([ -1 1]);
h.XDataSource = 't';
h.YDataSource = 'y';
rate = 10;
while 1
tic
pause(1/rate);
%java.lang.Thread.sleep(1000 * (1/rate))
toc
y = sin(2*pi*freq*t);
refreshdata(h);
drawnow % needed?
freq = freq + 0.1;
if freq > 40
freq = 4;
end
end
When I try this tic toc shows some inconsistent timing:
Elapsed time is 0.100041 seconds.
Elapsed time is 0.599817 seconds.
Elapsed time is 0.100195 seconds.
Elapsed time is 0.100100 seconds.
Elapsed time is 0.499797 seconds.
Elapsed time is 0.100046 seconds.
If I remove everything from the loop and leave just the pause command it behaves the same.
I tried using java's sleep command but that does not allow the plots to be updated until the loop is exited which is useless.
Update:
The results shown above happens whn I run this on Linux. I tried running the same code on Windows and it works fine. Not sure what could be the reason.
Accepted Answer
More Answers (1)
I have encountered a similar issue on my Linux operating system. Mr. Adam Danz has suggested using timeit, the the following approach is a little easier to understand for me:
rate = 10
tic
while toc < 1/rate
end
toc
This will replace to faulty pause command that varies from 0.1 to 0.5 seconds:
tic
pause(1/rate)
toc
4 Comments
Bruno Luong
on 26 Aug 2020
Edited: Bruno Luong
on 26 Aug 2020
+1. I do the same.
TIC/TOC is the most lean and reliable in my book.
TIMEIT do something different (benchmark some piece of code) and I don't like the overhead it requires by having interface with a function.
PAUSE is has great variability since it might trigger all kind of events beside the main task of PAUSING execution.
+1
To clarify, my answer was in response to a comment that was removed and recommends timeit() to benchmark the process for comparisons, not to control real-time applications.
jmore's method does a good job of avoiding the problems with pause(). However, users who are looking for very precise timing control should be aware of the limitations with tic/toc or any method of time control in Matlab.
As indicated in the documentation, tic/toc becomes unreliable for durations less than 0.1 sec. But even for larger durations there is unavoidable variability in the results. The plots below show the timing of 16 different durations repeated 10 times using the method in jmore's answer (with some slight changes). Results are jittered along the x axis to prevent overlap.

Performed on Windows 10 Pro Vs 10.0 (Matlab Online) using Matlab version 9.7.0.1434023 (R2019b) Update 6
To reproduce this analysis:
nReps = 10;
rate = [.001,.005,.01,.02,.05,.1,.11,.12,.15,.2,.5,1,1.5,2,5]; % seconds
nMinutes = sum(nReps.*rate)/60;
wb = msgbox(sprintf('This will take approximately %.1f minutes.', nMinutes), 'Confirm');
uiwait(wb)
dur = zeros(numel(rate),nReps);
for j = 1:numel(rate)
for i = 1:nReps
s = tic;
while toc(s) < rate(j)
end
dur(j,i) = toc(s);
end
end
mu = mean(dur,2);
sd = std(dur,[],2);
err = dur - rate(:);
clf()
tiledlayout(2,1)
t(1) = nexttile;
hold on
errorbar(mu,sd,'Marker', 'none', 'DisplayName', '+/-1 std')
xJitter = (1:numel(rate))' + (rand(numel(rate),nReps)-.5)/2;
plot(xJitter, dur, 'bo', 'DisplayName', 'all iterations')
plot(1:numel(rate), mu, 'rd', 'DisplayName', 'mean')
set(gca, 'XTick', 1:numel(rate), 'XTickLabel', rate)
xlabel('Wait time requested (sec)')
ylabel(['Mean clocked wait time (sec)',newline,'(plus some overhead)']);
title(['Timing results for various durations',newline,'across ',num2str(nReps),' reps'])
legend()
t(2) = nexttile;
plot(xJitter, err, 'bo', 'DisplayName', 'all iterations')
set(gca, 'XTick', 1:numel(rate), 'XTickLabel', rate, 'YScale', 'log')
xlabel('Wait time requested (sec)')
ylabel('Error (measured minus requested, sec)');
title(['Tic|Toc error for various durations',newline,'across ',num2str(nReps),' reps'])
Bruno Luong
on 26 Aug 2020
@Adam: Why there is an horizontal dispersion in the plot?I mean in your code the xaxis is plotted with 1:numel(rate) yet I see the points are dispersed horizontally. Odd.
Adam Danz
on 26 Aug 2020
I must have added that after copying the code to the comment. The comment states, "Results are jittered along the x axis to prevent overlap ", otherwise many of the points would lay on top of eachother.
To jitter the points,
xJitter = (1:numel(rate))' + (rand(numel(rate),nReps)-.5)/2;
plot(xJitter, dur, 'bo', 'DisplayName', 'all iterations')
I'll fix that in my comment. Thanks for pointing that out.
Categories
Find more on Parallel Computing Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!