One of the key assets in your suite of software testing tools is the Profiler, and you should get to know it well. The Profiler is “standard equipment” with most software development environments and has a wide array of capabilities to help point out weak areas of the code, to demonstrate the bottlenecks where most of the time is being spent, to find memory leaks, etc.
A few days ago, I needed to use the Matlab Profiler for some code I was working on and decided that it would be a good article because of the amount of run-time that the Profiler helped me save by pointing out a specific function that was, unnecessarily, taking the most time.
I’d been updating some old Matlab code – this particular function processes (parses, manipulates, assembles, etc.) a large number of ASCII text files (over three hundred files with 7-8,000 rows in each file) which can be time-intensive (much slower than just crunching numbers). But in this case, the run time of over 1,200 seconds seemed excessive – as shown below. Keep in mind that this code is running on a relatively new desktop with an SSD drive and an Intel i7-9700 processor with 8 cores – so I expected the function to run faster (a gut feeling).
Given that I didn’t know where to start looking, I decided it was best to run the Matlab Profiler to see if there were any functions that were slowing down the process unnecessarily. The quick way in Matlab to launch the Profiler is to simply have the function opened and then, in the Editor tab, click on “Run and Time” as shown below.
The run-time with the Profiler, shown below, was longer than the original run because of time spent by the Profiler performing its measurements.
At the end of the run, a Profiler summary was generated, and is shown below. mn is the main function in this example – note that Profiler shows that the function dateCheck, called by mn, seemed to be the resource hog as it was used for 1,183 seconds out of the total of 1,473 seconds. So, the first step was to click on mn to dig down into the Profiler trace.
After clicking on the mn function (above) the next level down is shown below. The top line in the mn function diagnostic page (below), shows that [ds] = dateCheck(ds) is taking up 80.6% of the run-time. Thus the function dateCheck, called by mn, is the culprit and the next step is to click on dateCheck lower down in the diagnostic page (see the red arrow below) and dig further down.
The Profiler summary then takes us to the next level down into the dateCheck function diagnostic page – and the line of code, in the dateCheck function, that uses the most resources is at the top of the diagnostic page (shown below). The children functions are shown below that section and the main culprit is the Matlab function datenum (see red arrow below)
So the issue is the Matlab datenum function, which is used in my dateCheck function.
Now we go to my dateCheck function in the Matlab source code file and find the line – currDateNum = datenum(tDate) – as shown below. That is the culprit, which is apparently causing a big drain of resources.
The next step is search the forums for a solution – the question is, why does this function take an excessive amount of time? A quick search found the very useful solution shown below. The answer is that the function datenum works much more efficiently when the date format is specified in the datenum argument list (instead of the function having to figure out the format itself).
With answer in-hand, the next step is to implement the solution – that is, specify the date format in the datenum argument, as shown below.
With the solution implemented, the final step is to re-run the software and see how much time was saved with this solution. As shown below, the run time was 571 seconds vs the original run time of 1,218 seconds!!
Now you understand that the Profiler is your best friend!! And keep in mind that it can not only save you a lot of time with your software runs but it can help you debug other issues as well.
Most software development environments or toolchains have profilers built into them. The example below is for NetBeans running a Java project. In this case I selected specific methods to be tested (profiled) and the percentage of run-time displayed. Profilers, such as Valgrind, used in Linux for C/C++ applications, are commonly used to detect memory leaks.