While solving it, it reminded me of a significant optimisation I made some years ago. Around 2014-2015, I was on a placement year away from my computer science degree. I had a 12 month placement working for the Science and Technology Facilities Council, a public sector gig which had me working on Mantid, an open source data analysis application primarily for use on neutron scattering experiments. That is, data from their particle accelerator. It was a fun first experience of professional software development and a good example of well written and maintained academic software.
One task I had was to improve the performance of various processing and filtering operations that Mantid could apply to a user’s dataset. One such operation required determining the intersection of many pairs of axis-aligned bounding boxes.
This is a very simple calculation, but my profiling informed me that it was taking the vast majority of the eight minute runtime of this particular process.
The intersection test was defined like this:
This function was being called thousands and thousands of times on many pairs of axis-aligned bounding boxes that very rarely overlapped. The result was a deluge of non-stop exception handling.
Fixing that is simple enough fortunately, so I changed the function to look like this:
I knew that this would improve the performance, but I didn’t appreciate just what a difference it would make.
The total runtime for the processing decreased from eight minutes down to just eight seconds. Instead of requiring a tea break, the user could carry on working in just the time it takes to have a nice yawn and stretch at their desk.
So when people say exceptions are a terrible way to implement flow control, they aren’t kidding. It doesn’t just muddy the internal flow of your software and make it harder to reason about; it can have a significant user perceivable impact to the way your software performs.
To this day, this remains the most satisfying performance fix I’ve made in my professional career.