Speeding Up Your MATLAB Code and Using the Stopwatch Timer

If your MATLAB script is too slow you may wish to find out in which part of the script the time is wasted. There are many ways to find the time consuming part of the script, for example the Profiler function Run and Time, but the simplest way is tic and toc to be included in a MATLAB script.

The function tic starts a stopwatch timer to measure performance. The function toc reads the elapsed time from the stopwatch timer started with the tic function. You can use

tic,toc

to simply measure the time between two subsequent commands in MATLAB, which is about

Elapsed time is 0.000005 seconds.

on my computer. We were interested in this when we were thought about sending and receiving signals in the MATLAB/LEGO MINDSTORMS project: how much time actually passes between two commands in a procedural MATLAB code? If the first line of MATLAB code generates a pulse-shaped sound of a sender, can the receiver actually hear this sound when it is read in the next line of MATLAB code?

Two more relevant examples of the use of tic and toc is to demonstrate the importance of workspace utilization and allocation, and growing variables in for loops to be avoided. As an example, let us calculate the logarithm of i times j, for each 1000 values of i and j. First, we do this without pre-allocating memory for the resulting array A, and second we actually do pre-allocate memory by creating an array of i times j zeros.

clear, clc
n = 1000, m = 1000

tic
for i = 1 : n
   for j = 1 : m
      A(i,j) = log(i*j);
   end
end 
toc

clear A
A = zeros(n,m);
tic
for i = 1 : n
   for j = 1 : m
      A(i,j) = log(i*j);
   end
end 
toc

The difference is dramatic,

Elapsed time is 0.288219 seconds.
Elapsed time is 0.057361 seconds.

using pre-allocation of memory reduces the computing time to 20%. MATLAB does not, different from other languages such as FORTRAN77, require the definition of the dimension and type of an array. However, for and while loops that incrementally increase the size of a data structure each time through the loop can adversely affect performance and memory use and therefore pre-allocating the maximum amount of space for the arrays is recommended.

The second example of the use of tic and toc is to compare for loops with vectorized loops. MATLAB documentation always recommends to use vectorization for operations involving arrays. Vectorization describes revising loop-based, scalar oriented code to use MATLAB array operations. The advantage of vectorized code, according to the documentation, is that the code appears more like tha mathematical expressions found in textbooks, making the code easier to understand. Furthermore, the vectorized code is much shorter than code with loops, reducing the opportunities to introduce programming errors. Last but not least the vectorized code runs much faster than the corresponding code containing loop, as the following example demonstrates.

clear, clc
n = 1000, m = 1000

A = 10*ones(n,m);
B = zeros(size(A));
tic
for i = 1 : n
   for j = 1 : m
     B(i,j) = log(A(i,j));
   end
end 
toc

clear A B
A = 10*ones(n,m);
B = zeros(size(A));
tic
    B = log(A);
toc

which yields

Elapsed time is 0.064817 seconds.
Elapsed time is 0.001388 seconds.

Despite the pre-allocation of memory, the vectorized version takes only about 3% of the for loop, which underlines the importance of vectorization when programming with MATLAB.

2 Replies to “Speeding Up Your MATLAB Code and Using the Stopwatch Timer”

  1. Hi, three comments:

    1) I generally encourage everyone to NOT start scripts with a “clear”-command. If not paying attention, a quick test of this script might clear all previous work in the current Matlab session without asking …

    2) (… more of a trick): One can avoid pre-allocation by iterating the for-loops in reverse order:
    tic
    for i = n:-1:1
    for j = m:-1:1
    A(i,j) = log(i*j);
    end
    end
    toc

    This way the array is intrinsically initialized. However, this might not always be possible and pre-allocation should be preferred coding style.

    3) The second example, which demonstrates the advantages of vectorization is problematic. Since this is a script, Matlab will not perform any optimizations on the code with the JIT-compiler. If you put this example into a function (just add “function test123” into first line and save) and re-run the example, you will see that the speed difference is gone.

    Generally, vectorization is a nice thing and can lead to shorter and easier to read code, but it often does not lead to performance gains anymore.

    In the end, all speed comparisons should be performed inside functions to make use of the JIT-compiler. Also, by using functions one avoids the need to issue clear-commands (see 1.), which can save a lot of pain down the road.

    1. Hi there, three replies:

      1) Do I understand that correctly, you assume that a user works on a complex MATLAB task for two hours, then copies the script from the blog into his/her Command Window and then he/she is annoyed that all his/her calculations are gone?

      2) Yes, but running the for loop backwards basically pre-allocates memory in the first run through the loop with n = 1000, m = 1000.

      3) That’s interesting but doing this still yields a significant difference on my machine:
      Elapsed time is 0.066573 seconds.
      Elapsed time is 0.004542 seconds.