Introduction

Matlab Logo A common bottleneck that may plague newer Matlab users involves the allocation of arrays, structures, and cells. Matlab allows automatic resizing of arrays, structures, and cells; this can lead to bottlenecks if the resizing continually occurs(for example, within a FOR loop). This tutorial will show you how to prevent these bottlenecks from occurring by preallocating the size of the array, structure, or cell.

Examples of Arrays being Automatically Resized

Matlab allows for dynamically resizing arrays. Let’s look at some simple examples of resizing arrays. Given the following vector:

myVector = [1 2 3 4 5];

We can attach a 6 to the end of the array in the following manner:

%method 1
myVector = [myVector 6]
 
%method 2
myVector(end+1) = 6;

In general, there isn’t a problem using the above code. But if you have this code within a large FOR loop, it can really hamper the execution time of your code.

An Example of Preallocating the Size of an Array

First, consider the following code, which DOES NOT preallocate the size of the array:

myVector = 1; %initialize the array
 
for x=2:50000
    myVector(x) = cos(myVector(x-1)) + myVector(x-1); %append elements onto array
end
disp('The code is done running!')

Next, consider the following code, which DOES preallocates the size of the array:

myVector = zeros(1,50000); %preallocate the size of the array
myVector(1) = 1; %initialize the first element of the array
 
for x=2:50000
    myVector(x) = cos(myVector(x-1)) + myVector(x-1); %append elements onto array
end
disp('The code is done running!')

The Speed Difference when Preallocating

If you run both examples, you will notice that the second case undoubtedly runs faster. Using the profile command (which was discussed here), we can verify and quantity the speed difference. On my computer, the first example took 3.391 seconds to run while the second example took 0.009 to run!! As you can see, the speed improvement was quite drastic.

What to do when the Preallocation size cannot be Determined

Sometimes, you won’t know the final size of the array. What can you do in this case? One solution is to use an upper bound on the preallocation of the array, and erasing the excess after the loop is done. For example, the following segment of code demonstrates the use of an upper bound. Because of the conditional if statement, we will not know in advance how large the array will be at the end.

myVector = zeros(1,1000); %preallocate array
count = 1; %initialize the variable
for x=1:1000;
    if(rand(1) > 0.5)  %if the randomly generated value is greater than 0.5
        count = count+1; %increment count
        myVector(count) = x; %assign value to array
    end
end
 
myVector = myVector(1:count); %remove excess elements

Preallocating Cell Arrays

Just like regular arrays, it is also possible to preallocate cell arrays using the cell command. There is a larger penalty levied when resizing cell arrays as opposed to regular arrays, so you will see larger speed gains when you preallocate cell arrays. Here is a quick example of how to preallocate a cell array:

myCell = cell(1,50000); %preallocate the cell array
myCell{1}= 1; %initialize the array
 
for x=2:50000
    myCell{x} = cos(myCell{x-1}) + myCell{x-1}; %append elements onto array
end
disp('The code is done running!')

Without preallocation, the code ran in 5.897 seconds. With preallocation, the code ran in 0.174 seconds!!

Preallocating Structures

Just like arrays and cell arrays, structures can also be preallocated. Here is a quick example on how you would preallocate a structure using the struct command:

myStructure(50000) = struct('field1',[],'field2',[]); %preallocate the structure
%everything before the 50,000th element is initialized to an empty matrix
 
myStructure(1).field1 = 1;
myStructure(1).field2 = 1; %this field isn't used in the for loop
 
for x=2:50000
    myStructure(x).field1 = cos(myStructure(x-1).field1) + myStructure(x-1).field1; %append elements onto array
end
disp('The code is done running!')

Another way of preallocating the structure is the following. This method is helpful when you want to initialize the structure to a specific value. In this case, all the values are defaulted to zero.

myStructure= repmat(struct('field1',0, 'field2', 0), 1, 50000);

In case you’re curious: Without preallocation, the code ran in 25.349 seconds. With preallocation, the code ran in 0.118 seconds!!

For more information on preallocating structures, you can visit the following mathworks link.

This is the end of the tutorial.