PERF: Cache ticks and ticklabel bboxes within each draw cycle#31012
PERF: Cache ticks and ticklabel bboxes within each draw cycle#31012scottshambaugh wants to merge 8 commits intomatplotlib:mainfrom
Conversation
e117b04 to
2ed48b9
Compare
|
Is this safe? Are you sure they are always identical? For example constrained layout draws twice and the Axes size and limits may have changed in the second draw. Or asking the other way round: if the updates are redundant, why are we doing them in the first place? |
|
As to why we're doing them multiple times in the first place - in 3D we need to access these values in the tick drawing and the grid drawing paths, which might not both be called so both needed to potentially refresh the calcs. In 2D, I don't see a reason - my hunch it was done without realizing the performance hit of recalculating that state each time. # axis.draw()
self._clear_ticks_cache()
ticks_to_draw = self._update_ticks(_use_cache=True)
tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer, _use_cache=True)
for tick in ticks_to_draw:
tick.draw(renderer)
self._update_label_position(renderer, _use_cache=True)
self.label.draw(renderer)
self._update_offset_text_position(tlb1, tlb2)
self.offsetText.set_text(self.major.formatter.get_offset())
self.offsetText.draw(renderer)
renderer.close_group(__name__)
self._clear_ticks_cache() |
9479900 to
7175a61
Compare
Fix test
7fca827 to
975fb24
Compare


PR summary
Towards #5665
Currently we are calling
_update_ticks()3 times per axis every draw call, and_get_ticklabel_bboxes2 times per axis. These calls take up about 35% of total draw time for an empty plot.We can eliminate 25% of total draw time by caching the results of these calculations every draw cycle. This introduces some state, but I think it's decently well guarded and the performance boost is definitely worth it.
Before & After
The circled red areas show the before & after runtime of
axis._update_label_positionwithinAxis.draw(). It runs after the cache values have been set by other functions, so we nearly completely eliminate its runtime.Before:

After:

Profiling script:
PR checklist