Let's see some tips and tricks on how to speed up MATLAB code
First we will look at ways to identify and measure how long our code takes
Then based on the type of slow down, we will follow best practices or use other MATLAB features to make it run faster
For our example, we are creating a random matrix A of size numElements using two for loops
Then, we are checking if an element of A is > 0.5
If it is, then we assign the value of A to B otherwise, we assign the value of -A to B
First we need to see how long it takes to run the script
The simplest way to do this is using the tic-tock commands
At the MATLAB command prompt, type the tick command, followed by the script or function evaluation, followed by toc
This shows you the elapsed time for the script or function. This code takes about 90 seconds or 1.5 minutes to run
When trying to improve this code, the first thing to check is the Code Analyzer
If this square is red, there are errors in your code
Orange means some improvements are suggested by MATLAB. Green says your code is all set!
In our case, it is orange and it says that our matrices A and B are changing size with every iteration
This could be an expensive operation for MATLAB to reshape variables every time
Especially when working with big matrices
One way to avoid this is to pre-allocate these matrices to a unknown size and only change the values inside and not the shape
To do this, initialize A and B to a zero matrix of numElement size
Using tik tok again, we see that the code takes only about one second to run that is close to 90 times speed up!
We would like to see how to improve this code further
There are no more Code Analyzer suggestions and tik tok doesn't give us any more pointers
To better measure code performance, we use the MATLAB profiler
Go to the Home tab and choose Run and time
This opens the MATLAB profiler window
Type the name of the MATLAB script or function and click on start profiling
We see how long the function took to run. Note that this time also includes some profiler overhead
So it will typically show you more time than tic toc
Click on the function name to get more information. We can see the time spent by MATLAB executing each of these lines
When addressing performance issues, this is a good place to identify where to focus our attention in terms of improvement
We are spending the most time in the random number assignment. This line is being executed 25 million times
The power of MATLAB is operating on matrices
Here we are writing nested for loops for matrix manipulation and can use MATLAB vectorization techniques to make it run faster
The rand function has a built-in mechanism to generate a matrix
Several MATLAB functions have this capability. Always look at the documentation to see the different ways to call a function
In our code, we can move the random number assignment to outside the loops
We use just a single line of MATLAB code by calling R and with numElements variable
Profiling this, we see that our code is faster now taking around 5 seconds to run as opposed to 6 before
We are also not spending as much time for random number generation
Next, we need to find a way to improve this logical statement
We are doing element wise comparison here and can use MATLAB logical indexing to vectorize this
Instead of assigning B to zeros, let's assign A to it
Then using a logical array, we can index into matrices to do a conditional assignment, to assign -A to B when we satisfy the condition
Profiling this, we see that our code is faster now taking less than 1 second to run as opposed to 5 before
We can also see that all lines are executed only once, and we have removed all the loops
After all these optimizations, now we can compare the code iterations
Plotting the runtime on a semi-log scale, we see the pre-populated results here
We started close to 100 seconds run time and now able to get less than 1 second. That is almost 100 times speed up!
Let's look at another example
We are reusing the optimized code from before. In addition, we are calculating the maximum eigen value of the B matrix
We are doing this for 24 different B matrices. Using tic toc, we can see that the code takes about 100 seconds to run
We are spending the most time calculating the eigenvalues in the loop, and do not see potential for improving the code inside the loop
In such cases, we should be able to use the multiple cores in our machine and solve each of the loop iteration tasks separately and then combine the results
We can do this using the Parallel Computing Toolbox
Type parpool at the MATLAB command prompt to create a parallel pool of MATLAB workers
These individual workers can then be assigned tasks
I now have six workers at my disposal
This depends on the number of cores in your machine. To use them, we will change our for loop to a parfor loop
Now using tic toc, we see that our code is faster now taking around 250 seconds to run as opposed to 120 before
That is about 2 times speed
Note that doing parallel tasks comes with its own time penalties such as communication overhead and setting up the parallel pool
It is recommended to do some timing experiments to make sure that changing to parallel execution is actually worth it
Also note that not all code that is serial is not easily parallelizable like our case
Look at the resources section to find more documentation about this
In general, we have looked at only a select few tips and tricks to speed up MATLAB code. There are several other ways.
Look at the MATLAB Acceleration page linked in the resources section to get more information about the ways discussed here in addition to other ways as well