[See Accelerating MATLAB using MEX-files for tips on speeding up MATLAB through profiling, vectorization, and compilation.]
Most MATLAB users want their code to be fast, especially when it is processing very large data sets. Because memory performance has not increased at the same rate as CPU performance, code today is often "memory-bound," its overall performance limited by the time it takes to access memory.
Fortunately, with a little knowledge of how MATLAB stores and accesses data, you can avoid inefficient memory usage and improve the speed of your code.
This article describes three ways to improve the performance of memory-bound code:
- Preallocate arrays before accessing them within loops
- Store and access data in columns
- Avoid creating unnecessary variables
In each case we will compare the execution speed of a code segment before and after applying the technique. To ensure the best performance, the code segments are all timed in function M-files, not script M-files. As memory performance is machine-dependent, the performance tests were carried out on two different machines .
Preallocate Arrays Before Accessing them Within Loops
When creating or repeatedly modifying arrays within loops, always allocate the arrays beforehand. Of all three techniques, this familiar one can give the biggest performance improvement.
The code segments in Figure 1 use a for loop to calculate a sequence of numbers based on the equation, x(k) = 1.05* x(k-1), equal to the annual balance of a bank account earning a 5% interest rate.
Figure 1. Preallocating arrays. Code segment 2 executes in 99.8% less time (580 times faster) than segment 1 on machine A, and in 99.7% less time (475 times faster) than segment 1 on machine B.
Why Code Segment 2 is Faster
The MATLAB language does not require you to declare the types and sizes of variables before you use them. As a result, you can increase the size of an array merely by indexing into it at a point larger than the current size. This approach is convenient for quick prototyping of code, but each time you use it, MATLAB must allocate memory for a new larger array and then copy the existing data into it. Code that repeats this procedure several times, as in a loop, is slow and inefficient.
In one step, code segment 2 preallocates the entire array x to the largest size that it needs to be. No more memory allocation is then required during the execution of the code. If the M-Lint code checker finds an opportunity to preallocate, it issues a warning.
Store and Access Data in Columns
When processing 2-D or N-D arrays, access your data in columns and store it so that it is easily accessible by columns.
The code segments in Figure 2 copy the positive values of the 2-D array x to a new array, y.
Figure 2. Storing and accessing data in columns. Code segment 2 executes in 33% less time than segment 1 on machine A, and in 55% less time than segment 1 on machine B.
Why Code Segment 2 is Faster
Modern CPUs use a fast cache to reduce the average time taken to access main memory. Your code achieves maximum cache efficiency when it traverses monotonically increasing memory locations. Because MATLAB stores matrix columns in monotonically increasing memory locations, processing data column-wise results in maximum cache efficiency.
1. Machine A is a Lenovo T60 ThinkPad, 1.83GHz Intel Core Duo T2400 processor, 2MB L2 cache, 2GB RAM, 32-bit Windows XP. Machine B is a Dual 2.1GHz AMD Opteron 248 processor machine , 1MB L2 Cache, 1GB RAM, 64-bit Linux.