Improve code efficiency ↩
- RoboFont (& embedded) APIs
- Generic programming considerations
You had a nice idea for a tool to support your workflow, and after a few attempts with code, it’s “working”. It does what you need it for, but, to be honest, it’s quite slow. It’s causing some lagging, and you’d like it to be snappier. As developers, we often face this situation, when “working” is not enough. Speed of execution and smooth interactions are also part of the equation, especially for real-time tools. Here you can find some ideas to improve the efficiency of your code.
RoboFont (& embedded) APIs
Subscriber to handle events and delays
One of the key aspects of efficient code is to avoid redundant work. When dealing with events in a real-time tool, notifications can shoot at an impressive speed and impressive amount.
Subscriber provides a powerful interface to watch application and font data events with event coalescing setup out-of-the-box. In other words,
Subscriber let’s you react to user notifications only when needed.
With RoboFont 4.0 came a new drawing API for the glyph editor window. If you still have tools drawing in the glyph editor with
mojo.drawingTools and you want to make them faster, start by updating the drawing routines to merz. Speed and detail will improve greatly.
Use Defcon Representations when possible
Avoiding redundant work sometimes means storing some data generated by our tool in memory for later use. Picking up a value from a dictionary is less expensive than recalculating the area of a glyph. If the glyph outlines did not change since the last calculation, executing the calculation again is a waste of resources. Defcon representations are a very powerful way to cache any data generated from font data (Glyph, Font, Kerning…).
Pens are your friend
If you are dealing with outline data and not using pens, you are missing out. They are not necessarily faster than iterating over a contour, but they are easy to cache and reuse as their logic is incapsulated into a
Pen object. They are used all over the place in RoboFont, defcon, fontTools and drawBot. They can help you refactor some code and cache the results.
Frederik Berlaen wrote a useful extension to track and profile processes running in RoboFont. That’s a great way to check wheter your tool is using unexpected resources or making excessive function calls. You can find it on mechanic.
Generic programming considerations
Besides RoboFont-specific tips, there are a few aspects it’s worth looking at when refactoring code.
Space and time complexity
Evaluating the efficiency of some code does not happen necessarily with timers, most of the time it starts by analyzing the way it’s structured. And to easily compare some alternatives, you can use the Big O notation system. This great talk from PyCon2018 by Ned Batchelder gives a great introduction to the topic, highly recommended.