I recently did a quick optimization pass over glyphsLib, using FunctionTrace to improve performance by ~30% in under half an hour.  This is w

Quickly optimizing Python code with FunctionTrace

submited by
Style Pass
2021-10-27 20:00:16

I recently did a quick optimization pass over glyphsLib, using FunctionTrace to improve performance by ~30% in under half an hour. This is writeup of my approach, which should be mostly extensible to optimizing other codebases. Hopefully this writeup gives you a sense for how productive non-sampled profilers such as FunctionTrace can be when it comes to optimizing code, as well as exploring a new codebase. NOTE: This article includes high-resolution images, and to get the most out of it you'll need to view them at their original size. As such, it may not be an enjoyable experience on mobile. A few important things before we start: This exploration was driven by a bug report submitted for FunctionTrace where it OOMed on noto-amalgamated after generating too large of a profile. This led me to optimize for number of function calls rather than strictly performance. Luckily these tend to be highly correlated in Python. I'd never seen or heard of this library before loading it in FunctionTrace. As a result, I didn't try to make broader algorithmic changes, and I attempted to make small targeted changes that were likely to be correct rather than more significant refactors. This was a quick hack-and-slash optimization session. No measurements were taken for intermediate optimizations, and my benchmark consisted of running the before/after code once each on an unloaded CPU via time — nothing involved with this process was rigorous!

FunctionTrace is a low-overhead non-sampled profiler for Python (which I've written about before) that uses the Firefox Profiler as a GUI. Earlier this month I received a bug report saying that it was crashing with an out-of-memory error when run on noto-amalgamated, a project that uses Noto. After reproducing the issue, it became obvious that FunctionTrace on this tool generated too much data for the current version of the Firefox Profiler to handle. While there are some interesting options for solving this in the future, I wanted to unblock the immediate use-case. The majority of the profiler information FunctionTrace emits comes from recording information on every function call entry and exit, so if we could quickly reduce the number of function calls we'd be able to profile proportionally more of the program's execution.

Leave a Comment