Techniques for Improving Performance

Vectorizing Loops

The MATLAB software uses a matrix language, which means it is designed for vector and matrix operations. You can often speed up your M-file code by using vectorizing algorithms that take advantage of this design. Vectorization means converting for and while loops to equivalent vector or matrix operations.

Simple Example of Vectorizing

Here is one way to compute the sine of 1001 values ranging from 0 to 10:

i = 0;
for t = 0:.01:10
    i = i + 1;
    y(i) = sin(t);
end

A vectorized version of the same code is

t = 0:.01:10;
y = sin(t);

The second example executes much faster than the first and is the way MATLAB is meant to be used. Test this on your system by creating M-file scripts that contain the code shown, and then using the tic and toc functions to time the M-files.

Advanced Example of Vectorizing

repmat is an example of a function that takes advantage of vectorization. It accepts three input arguments: an array A, a row dimension M, and a column dimension N.

repmat creates an output array that contains the elements of array A, replicated and "tiled" in an M-by-N arrangement:

A = [1 2 3; 4 5 6];

B = repmat(A,2,3);
B =
    1    2    3    1    2    3    1    2    3
    4    5    6    4    5    6    4    5    6
    1    2    3    1    2    3    1    2    3
    4    5    6    4    5    6    4    5    6

repmat uses vectorization to create the indices that place elements in the output array:

function B = repmat(A, M, N)

% Step 1 Get row and column sizes
[m,n] = size(A); 

% Step 2 Generate vectors of indices from 1 to row/column size
mind = (1:m)'; 
nind = (1:n)';

% Step 3 Create index matrices from vectors above
mind = mind(:,ones(1, M));
nind = nind(:,ones(1, N));

% Step 4 Create output array
B = A(mind,nind);

Step 1, above, obtains the row and column sizes of the input array.

Step 2 creates two column vectors. mind contains the integers from 1 through the row size of A. The nind variable contains the integers from 1 through the column size of A.

Step 3 uses a MATLAB vectorization trick to replicate a single column of data through any number of columns. The code is

B = A(:,ones(1,nCols))

where nCols is the desired number of columns in the resulting matrix.

Step 4 uses array indexing to create the output array. Each element of the row index array, mind, is paired with each element of the column index array, nind, using the following procedure:

  1. The first element of mind, the row index, is paired with each element of nind. MATLAB moves through the nind matrix in a columnwise fashion, so mind(1,1) goes with nind(1,1), and then nind(2,1), and so on. The result fills the first row of the output array.

  2. Moving columnwise through mind, each element is paired with the elements of nind as above. Each complete pass through the nind matrix fills one row of the output array.

Functions Used in Vectorizing

Some of the most commonly used functions for vectorizing are as follows

Function

Description

all

Test to determine if all elements are nonzero

any

Test for any nonzeros

cumsum

Find cumulative sum

diff

Find differences and approximate derivatives

find

Find indices and values of nonzero elements

ind2sub

Convert from linear index to subscripts

ipermute

Inverse permute dimensions of a multidimensional array

logical

Convert numeric values to logical

ndgrid

Generate arrays for multidimensional functions and interpolation

permute

Rearrange dimensions of a multidimensional array

prod

Find product of array elements

repmat

Replicate and tile an array

reshape

Change the shape of an array

shiftdim

Shift array dimensions

sort

Sort array elements in ascending or descending order

squeeze

Remove singleton dimensions from an array

sub2ind

Convert from subscripts to linear index

sum

Find the sum of array elements

Preallocating Arrays

for and while loops that incrementally increase, or grow, the size of a data structure each time through the loop can adversely affect performance and memory use. Repeatedly resizing arrays often requires that MATLAB spend extra time looking for larger contiguous blocks of memory and then moving the array into those blocks. You can often improve on code execution time by preallocating the maximum amount of space that would be required for the array ahead of time.

The following code creates a scalar variable x, and then gradually increases the size of x in a for loop instead of preallocating the required amount of memory at the start:

x = 0;
for k = 2:1000
   x(k) = x(k-1) + 5;
end

Change the first line to preallocate a 1-by-1000 block of memory for x initialized to zero. This time there is no need to repeatedly reallocate memory and move data as more values are assigned to x in the loop:

x = zeros(1, 1000);
for k = 2:1000
   x(k) = x(k-1) + 5;
end

Preallocation Functions

Preallocation makes it unnecessary for MATLAB to resize an array each time you enlarge it. Use the appropriate preallocation function for the kind of array you are working with.

Array Type

Function

Examples

Numeric

zeros

y = zeros(1, 100);

Cell

cell

B = cell(2, 3);
B{1,3} = 1:3;
B{2,2} = 'string';

Preallocating a Nondouble Matrix

When you preallocate a block of memory to hold a matrix of some type other than double, avoid using the method

A = int8(zeros(100));

This statement preallocates a 100-by-100 matrix of int8 first by creating a full matrix of doubles, and then converting each element to int8. This costs time and uses memory unnecessarily.

The next statement shows how to do this more efficiently:

A = zeros(100, 'int8');

Use Distributed Arrays for Large Datasets

This topic is described in the "Parallel Math" section of the Parallel Computing Toolbox™ documentation.

When Possible, Replace for with parfor (Parallel for)

This topic is described in the "Parallel for-Loops" section of the Parallel Computing Toolbox documentation.

Multithreading Capabilities in MATLAB

See Implicit Multiprocessing to learn more about making use of multithreaded computation.

Limiting M-File Size and Complexity

Running programs that are unusually large or complex can put a strain on your system's resources. For example, a program that nearly exceeds memory capacity may work some of the time and sometimes not, depending on the commands it uses and on what other applications are running at the time. An example of unnecessary complexity might be having a large number of if and else statements where switch and case might be more suitable. This can also lead to performance and space problems. If you see the following error message displayed, this is likely to be the source of the problem:

The input was too complicated or too big for MATLAB to parse

If you have an M-file that includes thousands of variables or functions, tens of thousands of statements, or hundreds of language keyword pairs (e.g., if-else, or try-catch), then making some of the changes suggested here is likely to not only boost its performance and reliability, but should make your program code easier to understand and maintain as well.

Coding Loops in a MEX-File

If there are instances where you cannot vectorize and must use a for or while loop, consider coding the loop in a MEX-file. In this way, the loop executes much more quickly since the instructions in the loop do not have to be interpreted each time they execute.

See Using MEX-Files to Call C and Fortran Programs in the External Interfaces documentation.

Assigning to Variables

For best performance, keep the following suggestions in mind when assigning values to variables.

Changing a Variable's Data Type or Dimension

Changing the class or array shape of an existing variable slows MATLAB down as it must take extra time to process this. When you need to store data of a different type, it is advisable to create a new variable.

This code changes the type for X from double to char, which has a negative impact on performance:

X = 23;
     .
-- other code  --
     .
X = 'A';                  % X changed from type double to char
     .
-- other code  --

Assigning Real and Complex Numbers

Assigning a complex number to a variable that already holds a real number impacts the performance of your program. Similarly, you should not assign a real value to a variable that already holds a complex value.

Operating on Real Data

When operating on real (i.e., noncomplex) numbers, it is more efficient to use MATLAB functions that have been designed specifically for real numbers. The following functions return numeric values that are real.

Function

Description

reallog

Find natural logarithm for nonnegative real arrays

realpow

Find array power for real-only output

realsqrt

Find square root for nonnegative real arrays

Using Appropriate Logical Operators

When performing a logical AND or OR operation, you have a choice of two operators of each type.

Operator

Description

&, |

Perform logical AND and OR on arrays element by element

&&, ||

Perform logical AND and OR on scalar values with short-circuiting

In if and while statements, it is more efficient to use the short-circuiting operators, && for logical AND and || for logical OR. This is because these operators often do not have to evaluate the entire logical expression. For example, MATLAB evaluates only the first part of this expression whenever the number of input arguments is less than three:

if (nargin >= 3) && (ischar(varargin{3}))

See Short-Circuit Operators in the MATLAB documentation for a discussion on short-circuiting with && and ||.

Overloading Built-In Functions

Overloading MATLAB built-in functions on any of the standard MATLAB data classes can negatively affect performance. For example, if you overload the plus function to handle any of the integer classes differently, you may hinder certain optimizations in the MATLAB built-in function code for plus, and thus may slow down any programs that make use of this overload.

Functions Are Generally Faster Than Scripts

Your code executes more quickly if it is implemented in a function rather than a script.

Load and Save Are Faster Than File I/O Functions

If you have a choice of whether to use load and save instead of the low-level MATLAB file I/O routines such as fread and fwrite, choose the former. load and save have been optimized to run faster and reduce memory fragmentation.

Avoid Large Background Processes

Avoid running large processes in the background at the same time you are executing your program in MATLAB. This frees more CPU time for your MATLAB session.

  


 © 1984-2008- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS