Make sizing computation much faster for nested containers - #991
Merged
Merged
Conversation
Collaborator
|
Super useful change. |
When nesting Columns, Pile and other containers, calls to widget.sizing() can
become very slow, especially on slower architectures. Profiling showed that we
are spending a big slice of time in enum.IntFlag dunder methods (i.e, __new__,
__or__, __and__ and __call__) and _get_value (which is used by dunder methods).
111191 0.014 0.000 0.014 0.000 enum.py:1129(__new__)
333573 0.039 0.000 0.053 0.000 enum.py:1544(_get_value)
56592 0.040 0.000 0.086 0.000 enum.py:1551(__or__)
54599 0.037 0.000 0.080 0.000 enum.py:1562(__and__)
111191 0.021 0.000 0.035 0.000 enum.py:726(__call__)
Although enum.IntFlag feels much cleaner than enum.IntEnum for the job, the
performance of enum.IntEnum is much better.
In Subiquity, switching from enum.IntFlag to enum.IntEnum causes calls to
Pile.sizing() to be about 10 times faster.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
ogayot
force-pushed
the
faster-sizing
branch
from
February 18, 2025 08:47
873ffa3 to
e91b0aa
Compare
Contributor
Author
Implemented thanks! I had to make further modifications to make the tests pass. While There's a bit of a tradeoff between performance and readability here. I'm open for suggestions to make this better :) |
Pull Request Test Coverage Report for Build 13386614645Details
💛 - Coveralls |
penguinolog
approved these changes
Feb 18, 2025
Collaborator
|
Release 3.0 expected next week |
netbsd-srcmastr
pushed a commit
to NetBSD/pkgsrc
that referenced
this pull request
May 11, 2025
Urwid 3.0.2 =========== 2025-05-07 Bug fixes 🕷 ++++++++++++ * Bugfix: Corner case: Scrollbar render for only 1 row height by @penguinolog in urwid/urwid#1021 Urwid 3.0.1 =========== 2025-05-07 Bug fixes 🕷 ++++++++++++ * Packaging: drop setup.py and adjust requirements by @penguinolog in urwid/urwid#1018 Not updated `setup.py` lead to wrong metadata and mark of release 3.0.0 as Python 3.7 compatible. Since urwid is distribluted in the pre-packaged format (wheel), missing `setup.py` will not affect old toolchain users except special cases (manually enforced sdist usage). * Python 3.14 compatibility: adjust `AsyncioEventLoop` by @penguinolog in urwid/urwid#1019 Urwid 3.0.0 =========== 2025-05-06 Breaking Changes ⚠ ++++++++++++++++++ * Drop deprecated `__super` property by @penguinolog in urwid/urwid#956 * Drop deprecated `FlowWidget`, `BoxWidget` and `FixedWidget` widgets by @penguinolog in urwid/urwid#955 * Remove deprecated protected getter methods from the `Canvas` and `AttrSpec` by @penguinolog in urwid/urwid#958 * Remove support for the `bytes` based fonts by @penguinolog in urwid/urwid#961 * Remove deprecated `TermScroller` by @penguinolog in urwid/urwid#960 * Remove deprecated protected getter methods from the decoration widgets by @penguinolog in urwid/urwid#959 * Remove deprecated protected getter methods from the container widgets by @penguinolog in urwid/urwid#957 * Remove deprecated protected setters in the decoration widgets by @penguinolog in urwid/urwid#968 * Remove deprecated protected methods from the container widgets by @penguinolog in urwid/urwid#970 * Remove deprecated protected method `_set_done` from the `ProgressBar` by @penguinolog in urwid/urwid#971 New features 🗹 +++++++++++++++ * API Extension: make `CommandMap` `MutableMapping` by @penguinolog in urwid/urwid#969 * Make sizing computation much faster for nested containers by @ogayot in urwid/urwid#991 * `MetaSignals` subclass `ABCMeta` by @penguinolog in urwid/urwid#962 Deprecations ⚡ +++++++++++++++ * `MetaSuper` should be the last base for classes by @penguinolog in urwid/urwid#972 * Announce deprecated API removal versions by @penguinolog in urwid/urwid#999 Bug fixes 🕷 ++++++++++++ * Fix handling of WEIGHT selectable items in the `Pile` by @penguinolog in urwid/urwid#1006 Refactoring 🛠 ++++++++++++++ * Refactoring: micro optimizations of iterable items reconstruction by @penguinolog in urwid/urwid#1009 New Contributors ++++++++++++++++ * @ogayot made their first contribution in urwid/urwid#991
msk
pushed a commit
to msk/pkgsrc
that referenced
this pull request
May 11, 2026
Urwid 3.0.2 =========== 2025-05-07 Bug fixes 🕷 ++++++++++++ * Bugfix: Corner case: Scrollbar render for only 1 row height by @penguinolog in urwid/urwid#1021 Urwid 3.0.1 =========== 2025-05-07 Bug fixes 🕷 ++++++++++++ * Packaging: drop setup.py and adjust requirements by @penguinolog in urwid/urwid#1018 Not updated `setup.py` lead to wrong metadata and mark of release 3.0.0 as Python 3.7 compatible. Since urwid is distribluted in the pre-packaged format (wheel), missing `setup.py` will not affect old toolchain users except special cases (manually enforced sdist usage). * Python 3.14 compatibility: adjust `AsyncioEventLoop` by @penguinolog in urwid/urwid#1019 Urwid 3.0.0 =========== 2025-05-06 Breaking Changes ⚠ ++++++++++++++++++ * Drop deprecated `__super` property by @penguinolog in urwid/urwid#956 * Drop deprecated `FlowWidget`, `BoxWidget` and `FixedWidget` widgets by @penguinolog in urwid/urwid#955 * Remove deprecated protected getter methods from the `Canvas` and `AttrSpec` by @penguinolog in urwid/urwid#958 * Remove support for the `bytes` based fonts by @penguinolog in urwid/urwid#961 * Remove deprecated `TermScroller` by @penguinolog in urwid/urwid#960 * Remove deprecated protected getter methods from the decoration widgets by @penguinolog in urwid/urwid#959 * Remove deprecated protected getter methods from the container widgets by @penguinolog in urwid/urwid#957 * Remove deprecated protected setters in the decoration widgets by @penguinolog in urwid/urwid#968 * Remove deprecated protected methods from the container widgets by @penguinolog in urwid/urwid#970 * Remove deprecated protected method `_set_done` from the `ProgressBar` by @penguinolog in urwid/urwid#971 New features 🗹 +++++++++++++++ * API Extension: make `CommandMap` `MutableMapping` by @penguinolog in urwid/urwid#969 * Make sizing computation much faster for nested containers by @ogayot in urwid/urwid#991 * `MetaSignals` subclass `ABCMeta` by @penguinolog in urwid/urwid#962 Deprecations ⚡ +++++++++++++++ * `MetaSuper` should be the last base for classes by @penguinolog in urwid/urwid#972 * Announce deprecated API removal versions by @penguinolog in urwid/urwid#999 Bug fixes 🕷 ++++++++++++ * Fix handling of WEIGHT selectable items in the `Pile` by @penguinolog in urwid/urwid#1006 Refactoring 🛠 ++++++++++++++ * Refactoring: micro optimizations of iterable items reconstruction by @penguinolog in urwid/urwid#1009 New Contributors ++++++++++++++++ * @ogayot made their first contribution in urwid/urwid#991
jperkin
pushed a commit
to TritonDataCenter/pkgsrc
that referenced
this pull request
May 14, 2026
Urwid 3.0.2 =========== 2025-05-07 Bug fixes 🕷 ++++++++++++ * Bugfix: Corner case: Scrollbar render for only 1 row height by @penguinolog in urwid/urwid#1021 Urwid 3.0.1 =========== 2025-05-07 Bug fixes 🕷 ++++++++++++ * Packaging: drop setup.py and adjust requirements by @penguinolog in urwid/urwid#1018 Not updated `setup.py` lead to wrong metadata and mark of release 3.0.0 as Python 3.7 compatible. Since urwid is distribluted in the pre-packaged format (wheel), missing `setup.py` will not affect old toolchain users except special cases (manually enforced sdist usage). * Python 3.14 compatibility: adjust `AsyncioEventLoop` by @penguinolog in urwid/urwid#1019 Urwid 3.0.0 =========== 2025-05-06 Breaking Changes ⚠ ++++++++++++++++++ * Drop deprecated `__super` property by @penguinolog in urwid/urwid#956 * Drop deprecated `FlowWidget`, `BoxWidget` and `FixedWidget` widgets by @penguinolog in urwid/urwid#955 * Remove deprecated protected getter methods from the `Canvas` and `AttrSpec` by @penguinolog in urwid/urwid#958 * Remove support for the `bytes` based fonts by @penguinolog in urwid/urwid#961 * Remove deprecated `TermScroller` by @penguinolog in urwid/urwid#960 * Remove deprecated protected getter methods from the decoration widgets by @penguinolog in urwid/urwid#959 * Remove deprecated protected getter methods from the container widgets by @penguinolog in urwid/urwid#957 * Remove deprecated protected setters in the decoration widgets by @penguinolog in urwid/urwid#968 * Remove deprecated protected methods from the container widgets by @penguinolog in urwid/urwid#970 * Remove deprecated protected method `_set_done` from the `ProgressBar` by @penguinolog in urwid/urwid#971 New features 🗹 +++++++++++++++ * API Extension: make `CommandMap` `MutableMapping` by @penguinolog in urwid/urwid#969 * Make sizing computation much faster for nested containers by @ogayot in urwid/urwid#991 * `MetaSignals` subclass `ABCMeta` by @penguinolog in urwid/urwid#962 Deprecations ⚡ +++++++++++++++ * `MetaSuper` should be the last base for classes by @penguinolog in urwid/urwid#972 * Announce deprecated API removal versions by @penguinolog in urwid/urwid#999 Bug fixes 🕷 ++++++++++++ * Fix handling of WEIGHT selectable items in the `Pile` by @penguinolog in urwid/urwid#1006 Refactoring 🛠 ++++++++++++++ * Refactoring: micro optimizations of iterable items reconstruction by @penguinolog in urwid/urwid#1009 New Contributors ++++++++++++++++ * @ogayot made their first contribution in urwid/urwid#991
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.
Hello,
Today, I investigated a performance regression in Subiquity after moving from urwid 2.1.2 to urwid 2.6.10. It quickly turned out that Subiquity is relying too much on widget nesting and that the calls to
Pile.sizingstarted taking forever after #733 got merged.When nesting Columns, Pile and other containers, calls to
widget.sizing()can become very slow, especially in slower architectures. Profiling showed that we are spending a big slice of time inenum.IntFlagdunder methods (i.e,__new__,_get_value,__or__,__and__and__call__).Although
enum.IntFlagfeels cleaner thanenum.IntEnumfor the job, the performance ofenum.IntEnumis much better.In Subiquity, switching from
enum.IntFlagtoenum.IntEnumcauses calls toPile.sizing()to be about 10 times faster.Difference before/after this patch:
1069704 function calls (1056415 primitive calls) in 0.203 seconds
74088 function calls (60799 primitive calls) in 0.027 seconds
(yes, we have too much nesting... we need to fix it)
Benchmark with enum.IntFlag and enum.IntEnum
Checklist
masterbranchtoxsuccessfully in local environment