One of the reasons why people use MATLAB is that it enables users to express and try out ideas very quickly, without worrying too much about programming. This is great for researchers, but as algorithms become more complex it can lead to a misconception that MATLAB is slow. This article will focus on MATLAB Profiler as a tool to help improve MATLAB code.
As people improve their MATLAB skills they also develop a methodology and a deeper understanding of MATLAB to write better code. This article will help speed up that learning curve, with a simple example of calculating the nth number in a Fibonacci Sequence.
In Computer Science the Fibonacci Sequence is typically used to teach the power of recursive functions. The MATLAB code for a recursive implementation of finding the nth Fibonacci number in MATLAB looks like this:
function out = myFib1(in) % Recursive if in==1 || in==2 out = 1; else out = myFib1(in-1) + myFib1(in-2); end
At first glance this looks elegant and works nicely until a large value of in
is used. The natural question is: what is a good method to iteratively try different algorithms and test their performance.
Most people will start with tic
, toc
command. Others will use timeit
. More proficient users will probably use the MATLAB Profiler. People with a strong software background will write Unit Tests and use the Performance Testing Framework that MathWorks provides. This article will only use the MATLAB Profiler as it changed its look and feel in R2020a with Flame Graph.
So let’s start with using the MATLAB Profiler on myFib1(10)
by clicking the Run and Time
button under the Editor Tab in R2020a.
This Flame Graph shows that the same function was called 109 times. Each bar illustrates the execution time. Now that there is a benchmark, the question becomes: Is there a better way to implement calculating the Fibonacci Sequence, leveraging MATLAB strengths? Here are 3 other implementations:
- Using
for
loop: increasing memory in each iteration - Using
for
loop: only storing the last 2 values of Fibonacci sequence - Applying Binet‘s Formula
Increasing memory in each iteration
function out = myFib2(in) % For Loop: Increasing memory in each iteration if in==1 || in==2 out = 1; return end k = [1 1]; for idx = 3:in k(idx) = k(idx-1) + k(idx-2); end out = k(end);
Only storing the last 2 values of the Fibonacci Sequence
function out = myFib3(in) % For loop: Only storing the last 2 values of the Fibonacci Sequence if in==1 || in==2 out = 1; return end k = [1 1]; for idx = 1:in-2 k(3) = k(1) + k(2); k(1) = k(2); k(2) = k(3); end out = k(3);
Using Binet’s Formula
function out = myFib4(in) % Binet's Formula r = sqrt(5); phi = (1+r)/2; psi = (1-r)/2; out = (phi.^in - psi.^in)./r;
There is plenty to be said about each of the implementations, but what is interesting is how MATLAB Profiler is used to understand which implementation takes the longest and where the bottleneck is.
Here are the results:
MATLAB Profiler shows which algorithm took the longest, and dive into each file to see coding suggestions and which line is the most computationally expensive. Most experienced MATLAB users will quickly agree that:
- MATLAB is fastest when operating on matrices
- Recursive functions are less efficient in MATLAB
- It is a best practice to not change variable sizes in loops
- Sometimes a deeper understanding of the problem can enable additional efficiency gains. In this case Binet’s Formula scales nicely with any value of
in
.
Here is a short video illustrating how quick and easy it is to use the MATLAB Profiler.
If you are interested in improving your MATLAB code, Contact Us and see how our services can help.