perf: eliminate per-frame allocations across all paint-hot paths and event dispatchers#245
Open
gmmcosta15 wants to merge 6 commits into
Open
perf: eliminate per-frame allocations across all paint-hot paths and event dispatchers#245gmmcosta15 wants to merge 6 commits into
gmmcosta15 wants to merge 6 commits into
Conversation
…SIP enum in screensaver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Select the type:
Eliminates repeated per-frame CPU work in the application's paint-hot paths and event dispatchers, reducing idle CPU from ~73% GIL to ~2% GIL (measured via py-spy on Raspberry Pi 5 aarch64).
list_model.py-QPainterPathcache keyed by(w, h)+painter.translate(); pre-computedQColorobjects; iconscaled()cache keyed byQSize;QFont/QFontMetricscache by point size;_get_tinted()LRU for tintedQPixmapcomposites; removedLosslessImageRenderinghint;handlePath.clear() + addEllipse()path reusedisplay_button.py- round-rectQPainterPathcache by(w, h);_get_font(pt)helper cachesQFontby point size; icon + secondary iconscaled()cache byQSize;QColorpre-computation for hover gradient and secondary text; removedLosslessImageRenderinghinttoggleAnimatedButton.py- iconscaled()cache keyed byQSize;handlePath.clear()reuse instead of freshQPainterPatheach frameblocks_button.py- backgroundQPainterPathand iconscaled()cache keyed byQSize; removed duplicateCE_PushButtonLabeldraw call and per-paintsetStyle()callmainWindow.py- 5 custom event types pre-computed as class-level constants; singleetype = event.type()call perevent()dispatch instead of one per branchscreensaver.py-_TOUCH_INTS: frozenset[int]stores raw.valueints;event.type().value in _TOUCH_INTSbypasses per-call SIP enum constructionloadWidget.py-show()replaced withsetVisible()override; 16ms animation timer is paused when the widget is hidden and resumed when shownfiles.py-installEventFilternarrowed toself.parent()withQApplicationfallback, reducing global filter scopefilesPage.py-_find_file_insert_positionusesenumerate(self._model.entries)instead ofrowCount()+model.index(i)+model.data()on every comparison, bypassing the SIP bridgeMotivation
py-spy profiling on the target Raspberry Pi 5 (aarch64) identified
paintEvent,eventFilter, and SIP bridge calls (rowCount,model.data) as the dominant GIL consumers during idle. All changes avoid repeated allocation (paths, fonts, colors, pixmaps) and SIP crossings on the hot path. No behavioral changes.