Waiting for the waitbar

I love matlab waitbar. I use it everywhere in my matlab code. I always have the feeling my code is running faster when a nice window show the progress of calculations being done. What a surprise I had  when I realized that Matlab waitbar function was significantly slowing down all my calculations.

h=waitbar(0,'Waiting...');
EndOfLoop=2000;
for i=1:EndOfLoop
waitbar(i/EndOfLoop,h);
end
delete(h);

If you run the following line while the Profiler is On, you will be very surprised. On my computer, a single update of the waitbar takes 30 ms. Now you will think that is not so much, but it is actually A LOT. As you can see just browsing through a for loop with 200 iterations takes 6 seconds ONLY because of the waitbar. This is rather slow.

A simple 100×100 matrix multiplications element wise (so about 10^4 multiplications at each iterations) take 100 times less time!

I did try to speed this up by looking at lower levels calls to the waitbar but Mathworks made it so nice and secure that you can’t access these.

So here is a work-around solutions (Until Mathworks actually fixes this issue). This is not of the best elegance but it works reliably : just limit your access to the function to just what is needed to inform you or your users of the current progress.

h=waitbar(0,'Waiting...');
EndOfLoop=200;

dividerWaitbar=10^(floor(log10(EndOfLoop))-1);

for i=1:EndOfLoop
if (round(i/dividerWaitbar)==i/dividerWaitbar)
waitbar(i/EndOfLoop,h);
end
end
delete(h);

This code just work out the biggest divider to limit waitbar access and keep  the number of calls to waitbar always in the tens whatever the number of iterations. The use of the logarithmic function is just to make sure it works as well for big or small numbers below 10.

NOTA : I submitted a bug report to Matlab about this issue as this is not a normal behavior. It was confirmed as an enhancement request. We will see if it is incorporated in Matlab 2013. In the meantime, I also recommend using multiWaitbar on the file exchange (from Mathworks actually) which is far more efficient, provides a better look and is more flexible. 

Related Posts

This entry was posted in Annoyances, Intermediate, Making interfaces, Optimizing your code. Bookmark the permalink.

4 Responses to Waiting for the waitbar

  1. I was also annoyed by the waitbar slowness. In case you have no GUI (so you directly print on the console) I find better to use text-based progress bars, e.g.
    http://www.mathworks.com/matlabcentral/fileexchange/28067-text-progress-bar
    http://www.mathworks.com/matlabcentral/fileexchange/14773-statusbar

    Very nice blog by the way,

    • Jerome says:

      Thanks,
      I really encourage you to try out the multiWaitbar. It’s quite reasonable in speed.

      There is an internal check for only updating the waitbar for steps that increment more than one pixel on the screen (the standard matlab bar actually updates all the time even when the bar doesn’t need to move).

      • I will give it a try. :)
        By the way, on my PC (Windows 7, Chrome 31.0.1650.63 m) every time I load a page a popup appears telling me “Can’t find the brush for: matlabkey”. I do not know if the problem was already signaled by someone else.

  2. Ekran says:

    operations that try to update something on the screen are usually very slow, not only the waitbar in matlab, but in general if one wants to print sth on the screen or plot sth in lower level languages such as C# or so. I suppose this is because the update speed of the screen is around 25Hz and calling a function that can work with 25Hz at most a lot of times with a very higher frequency causes problems. So it is usually not the best idea to try to update the screen a lot of times, but one should rather bring it down to around 25Hz (or whatever the screen update speed is) or do it even slower.
    the way I personally do it is: I monitor the percentage and update the waitbar only if the new percentage is not equal to old percentage. sth like this:
    old_perc=0;
    for n=1:100000
    perc_new=round(100*n/100000);
    if(perc_new~=old_perc)
    %update waitbar here
    perc_old=perc_new
    end

    %do your other stuf…
    end

Leave a Reply