8
votes

I've been programming some MATLAB GUIs (not using GUIDE), mainly for viewing images and some other simple operations (such as selecting points and plotting some data from the images).

When the GUI starts, all the operations are performed quickly. However, as the GUI is used (showing different frames from 3D/4D volumes and perfoming the operations mentioned above), it starts getting progressively slower, reaching a point where it is too slow for common usage.

I would like to hear some input regarding:

  • Possible strategies to find out why the GUI is getting slower;
  • Good MATLAB GUI programming practices to avoid this;
  • Possible references that address these issues.

I'm using set/getappdata to save variables in the main figure of the GUI and communicate between functions.

(I wish I could provide a minimal working example, but I don't think it is suitable in this case because this only happens in somewhat more complex GUIs.)

Thanks a lot.

EDIT: (Reporting back some findings using the profiler:)

I used the profiler in two occasions:

  • immediatly after starting the GUI;
  • after playing around with it for some time, until it started getting too slow.

I performed the exact same procedure in both profiling operations, which was simply moving the mouse around the GUI (same "path" both times).

The profiler results are as follows:

enter image description here

I am having difficulties in interpreting these results... Why is the number of calls of certain functions (such as impixelinfo) so bigger in the second case?

Any opinions?

Thanks a lot.

2
Try this: forceGarbageCollection(). This is kind of java related thing. - huseyin tugrul buyukisik
Have you tried monitoring your memory usage while running the GUI over extended periods - is it generally very high or does it, for example, increase gradually over time as the GUI slows down? Are you using just MATLAB, or are you calling out to Java or MEXed C code anywhere? Are you using regular MATLAB variables, or are you using objects - and if so, are they value or handle class objects? - Sam Roberts
@SamRoberts: No, I have not tried to monitor memory usage while running the GUI. Will do and report back. Regarding the other questions, I'm just using MATLAB and only regular variables. Thanks. - fnery
Regarding the profiler results... Set breakpoints inside those functions and run the GUI again to figure out why they get called so many times. Maybe you're doing something like adding new axes or data and never removing the old ones. - shoelzer
as mentioned by @shoelzer, make sure you are simply updating graphic data, and not adding some over and over in your GUI. - Hoki

2 Answers

2
votes

The single best way I have found around this problem was hinted at above: forced garbage collection. Great advice though the command forceGarbageCollection is not recognized in MATLAB. The command you want is java.lang.System.gc()... such a beast.

I was working on a project wherein I was reading 2 serial ports at 40Hz (using a timer) and one NIDAQ at 1000Hz (using startBackground()) and graphing them all in real-time. MATLAB's parallel processing limitations ensured that one of those processes would cause a buffer choke at any given time. Animations would not be able to keep up, and eventually freeze, etc. I gained some initial success by making sure that I was defining a single plot and only updating parameters that changed inside my animation loop with the set command. (ex. figure, subplot(311), axis([...]),hold on, p1 = plot(x1,y1,'erasemode','xor',...); etc. then --> tic, while (toc<8) set(p1,'xdata',x1,'ydata',y1)...

Using set will make your animations MUCH faster and more fluid. However, you will still run into the buffer wall if you animate long enough with too much going on in the background-- especially real-time data inputs. Garbage collection is your answer. It isn't instantaneous so you don't want it to execute every loop cycle unless your loop is extremely long. My solution is to set up a counter variable outside the while loop and use a mod function so that it only executes every 'n' cycles (ex. counter = 0; while ()... counter++; if (~mod(counter,n)) java.lang.System.gc(); and so on.

This will save you (and hopefully others) loads of time and headache, trust me, and you will have MATLAB executing real-time data acq and animation on par with LabVIEW.

1
votes

A good strategy to find out why anything is slow in Matlab is to use the profiler. Here is the basic way to use the profiler:

profile on
% do stuff now that you want to measure
profile off
profile viewer

I would suggest profiling a freshly opened GUI, and also one that has been open for a while and is noticeably slow. Then compare results and look for functions that have a significant increase in "Self Time" or "Total Time" for clues as to what is causing the slowdown.