-
-
Notifications
You must be signed in to change notification settings - Fork 1k
adds Strip primitive #1444
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
adds Strip primitive #1444
Changes from all commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
6f82ad9
adds Strip primitive
willmcgugan 22fc4ad
tidy
willmcgugan 280ad91
simplify
willmcgugan e7d86ac
fix types
willmcgugan 073885e
fix types
willmcgugan 0bca0d9
optimization
willmcgugan 2719a22
docstrings for Strip
willmcgugan 3fd8fe2
tests
willmcgugan ac0acde
accidental check in
willmcgugan a2f380a
fix typing
willmcgugan 2024552
typing fix
willmcgugan 81bc2ea
changelog
willmcgugan 54992d2
Added FIFOCache
willmcgugan 1815792
fix repr
willmcgugan b4535c3
docstrings
willmcgugan 8007c61
simpler
willmcgugan 692fc25
use fifo for arrangement cache
willmcgugan 7eccedd
Removed import
willmcgugan d37050c
typing
willmcgugan aa57b09
remove fifo cache from widget
willmcgugan 3b7c60b
remove locks
willmcgugan fcd032e
merge changelog
willmcgugan f0ddf63
fix changelog
willmcgugan f102fcb
fix slots
willmcgugan 331a0ce
moar tests
willmcgugan 8113ff8
moar tests
willmcgugan 716db2c
Added all
willmcgugan 5382f5e
check len
willmcgugan 51b5ebe
don't need call to keys
willmcgugan 6091a91
micro optimization
willmcgugan 516ca72
Merge branch 'main' into strip-optimization
willmcgugan cce244d
changelog
willmcgugan 51c7fef
extend trips to line API
willmcgugan d6451b5
changelog
willmcgugan f13e8e7
simplify with strip
willmcgugan 57654a9
fix snapshot
willmcgugan 17ef328
sort imports
willmcgugan 7fa289a
better sleep
willmcgugan 51cfa23
docstring
willmcgugan 38858e4
timer update
willmcgugan 85582a4
timer fix for Windoze
willmcgugan 734b742
Added link
willmcgugan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| --- | ||
| draft: false | ||
| date: 2022-12-30 | ||
| categories: | ||
| - DevLog | ||
| authors: | ||
| - willmcgugan | ||
| --- | ||
| # A better asyncio sleep for Windows to fix animation | ||
|
|
||
| I spent some time optimizing Textual on Windows recently, and discovered something which may be of interest to anyone working with async code on that platform. | ||
|
|
||
| <!-- more --> | ||
|
|
||
| Animation, scrolling, and fading had always been unsatisfactory on Windows. Textual was usable, but the lag when scrolling made it a little unpleasant to use. On macOS and Linux, scrolling is fast enough that it feels close to a native app, and not something running in a terminal. Yet the Windows experience never improved, even as Textual got faster with each release. | ||
|
|
||
| I had chalked this up to Windows Terminal being slow to render updates. After all, the classic Windows terminal was (and still is) glacially slow. Perhaps Microsoft just weren't focusing on performance. | ||
|
|
||
| In retrospect, that was highly improbable. Like all modern terminals, Windows Terminal uses the GPU to render updates. Even without focussing on performance, it should be fast. | ||
|
|
||
| I figured I'd give it once last attempt to speed up Textual on Windows. If I failed, Windows would forever be a third-class platform for Textual apps. | ||
|
|
||
| It turned out that it was nothing to do with performance, per se. The issue was with a single asyncio function: `asyncio.sleep`. | ||
|
|
||
| Textual has a `Timer` class which creates events at regular intervals. It powers the JS-like `set_interval` and `set_timer` functions. It is also used internally to do animation (such as smooth scrolling). This Timer class calls `asyncio.sleep` to wait the time between one event and the next. | ||
|
|
||
| On macOS and Linux, calling `asynco.sleep` is fairly accurate. If you call `sleep(3.14)`, it will return within 1% of 3.14 seconds. This is not the case for Windows, which for historical reasons uses a timer with a granularity of 15 milliseconds. The upshot is that sleep times will be rounded up to the nearest multiple of 15 milliseconds. | ||
|
|
||
| This limit appears holds true for all async primitives on Windows. If you wait for something with a timeout, it will return on a multiple of 15 milliseconds. Fortunately there is work in the CPython pipeline to make this more accurate. Thanks to [Steve Dower](https://twitter.com/zooba) for pointing this out. | ||
|
|
||
| This lack of accuracy in the timer meant that timer events were created at a far slower rate that intended. Animation was slower because Textual was waiting too long between updates. | ||
|
|
||
| Once I had figured that out, I needed an alternative to `asyncio.sleep` for Textual's Timer class. And I found one. The following version of `sleep` is accurate to well within 1%: | ||
|
|
||
| ```python | ||
| from time import sleep | ||
| from asyncio import get_running_loop | ||
|
|
||
| async def sleep(sleep_for: float) -> None: | ||
| """An asyncio sleep. | ||
|
|
||
| On Windows this achieves a better granularity that asyncio.sleep | ||
|
|
||
| Args: | ||
| sleep_for (float): Seconds to sleep for. | ||
| """ | ||
| await get_running_loop().run_in_executor(None, time_sleep, sleep_for) | ||
| ``` | ||
|
|
||
| That is a drop-in replacement for sleep on Windows. With it, Textual runs a *lot* smoother. Easily on par with macOS and Linux. | ||
|
|
||
| It's not quite perfect. There is a little *tearing* during full "screen" updates, but performance is decent all round. I suspect when [this bug]( https://bugs.python.org/issue37871) is fixed (big thanks to [Paul Moore](https://twitter.com/pf_moore) for looking in to that), and Microsoft implements [this protocol](https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036) then Textual on Windows will be A+. | ||
|
|
||
| This Windows improvement will be in v0.9.0 of [Textual](https://github.com/Textualize/textual), which will be released in a few days. |
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
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it also clear hits and misses counts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hits and misses are a debugging aid to see how well the cache is performing. You generally want to know about past performance even when it is cleared.