4

I have a MATLAB GUI (developed in GUIDE) where I give the user the option to save certain data-structure variables (as a .mat file). However, this is a large .mat file and it can take up to a minute to save this file. Without any sort of progress indication, I have no way of telling the user when the file is saved (allowing them to perform other actions in the GUI). Is there a way of creating a waitbar that is linked to the progress of the save function? Any help would be appreciated!

DeeWBee
  • 695
  • 4
  • 13
  • 38
  • There is no way to monitor the progress of a save operation in MATLAB. The best you can do it pop up a dialog telling them that saving is ongoing and remove the dialog when it is complete. – Suever Jul 01 '16 at 16:02
  • @Suever thanks for the prompt reply! So how would I know when the save function has finished saving the file? – DeeWBee Jul 01 '16 at 16:04

1 Answers1

5

You cannot monitor the progress of the save command in MATLAB. This is because MATLAB does not perform the save operation in another thread, but rather uses the program's main thread which prevents you from performing any actions while saving the file.

You could provide a dialog that tells the user that the save is occuring and simply remove it when the save is complete.

dlg = msgbox('Save operation in progress...');

save('output.mat');

if ishghandle(dlg)
    delete(dlg);
end

A Potential Solution

If you really want to save multiple variables and monitor the progress, you could use the -append flag to save and append each variable independently.

vars2save = {'a', 'b', 'c', 'd'};
outname = 'filename.mat';

hwait = waitbar(0, 'Saving file...');

for k = 1:numel(vars2save)
    if k == 1
        save(outname, vars2save{k})
    else
        save(outname, vars2save{k}, '-append');
    end

    waitbar(k / numel(vars2save), hwait);
end

delete(hwait);

A Benchmark

I did a benchmark to see how this second approach affects the total save time. It appears that using -append to save each variable has less of a performance hit than expected. Here is the code and the results from that.

function saveperformance

    % Number of variables to save each time through the test
    nVars = round(linspace(1, 200, 20));

    outname = 'filename.mat';

    times1 = zeros(numel(nVars), 1);
    times2 = zeros(numel(nVars), 1);

    for k = 1:numel(nVars)
        % Delete any pre-existing files
        if exist('outname')
            delete(outname)
        end

        % Create variable names
        vars2save = arrayfun(@(x)['x', num2str(x)], 1:nVars(k), 'Uniform', 0);

        % Assign each variable with a random matrix of dimensions 50000 x 2
        for m = 1:numel(vars2save)
            eval([vars2save{m}, '=rand(50000,2);']);
        end

        % Save all at once
        tic
        save(outname, vars2save{:});
        times1(k) = toc;

        delete(outname)

        % Save one at a time using append
        tic
        for m = 1:numel(vars2save)
            if m == 1
                save(outname, vars2save{m});
            else
                save(outname, vars2save{m}, '-append');
            end
        end
        times2(k) = toc;
    end

    % Plot results
    figure
    plot(nVars, [times1, times2])

    legend({'All At Once', 'Append'})
    xlabel('Number of Variables')
    ylabel('Execution Time (seconds)')
end

enter image description here

Suever
  • 64,497
  • 14
  • 82
  • 101
  • Thanks! I didn't realize that it was that simple. – DeeWBee Jul 01 '16 at 16:17
  • 1
    @DeeWBee Be sure to checkout my update. I would be curious to see what the time penalty is if you use the `-append` option on your data. – Suever Jul 01 '16 at 17:26