Here are my findings after profiling the loading of Roboto-Regular.ufo.
- the Lib.update(...) call is expensive (4.9%), mainly because of postNotification and _set_dirty
- creating Lib is expensive, mainly because of beginSelfNotificationObservation (3.4%), _get_dispatcher is a large contributor of the time spent (2.5%) as it does a chain of calls from getfont to getlayerset to getlayer
- _set_dirty (0.5%)
- let Lib parent BaseDictObject constructor take an initial mapping arg (defaults to None) that it will forward to the dict ctor, this way we can set an initial value without dealing with the notifications system
- write a fast path for when _isLoading is set
- glyph.instantiateLib could pass the font object to the Lib, that would avoid the chain of calls to find a dispatcher
- Again, we need a way to set anchors without paying the cost of notifications
- write a fast path for when _isLoading is set
- Same
- don't enable notifications but in appendComponent, this way the glyphObjectPointPen can do:
component = self._glyph.instantiateComponent()
component.baseGlyph = baseGlyphName
component.transformation = transformation
component.identifier = identifier
self._glyph.appendComponent(component)
without sending three useless notifications.
ATTN: beginSelfNotificationObservation must be the first subscriber
ATTN: this would break calling addObserver on a "lone" component (but who cares?)
It seems the point of this is mostly to avoid creating Contour (?) yet it is still putting contours and points in temporary data structures..
- remove this machinery and optimize Contour to have low-cost constructors and data-setting capatibility that circumvent notifications
- we need to do less in the constructor
- don't set all the contourClass, pointClass etc. over-and-over for every glyph object. make those into class attributes
ATTN: those class args are cascading from Font -> LayerSet -> Layer -> Glyph with some subtleties e.g. libClass and guidelineClass should ideally match between Font and LayerSet.
NOTE: we can start by freezing those attrs only in Glyph
Not sure how much optimization room there is here, but I'm pretty sure it's non-trivial.
- rewrite plistlib to a more efficient version, with cython etc.