Skip to content
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

Decrease event loop latency by binding time.monotonic to loop.time directly #98288

Merged
merged 5 commits into from
Aug 14, 2023

Conversation

bdraco
Copy link
Member

@bdraco bdraco commented Aug 12, 2023

I've been running this for a while with good results. Not expecting an side effects since its calling the exact same path under the hood without the python method call wrapper.

Proposed change

This is a small improvement to decrease event loop latency. While the original goal was to reduce Bluetooth connection time latency, everything using asyncio is a bit more responsive as a result.

base_events.py is almost always the top file in profiles since _run_once is there. This change eliminated at least 10% of the run time in that file, ~13.8% in when profiling as the time call is made upwards of ~30000 times per minute on systems with 4 bluetooth remotes/local adapters. The python time method call that wrapped time.monotonic, is the most frequently called non built-in method on all my production systems, and it was more expensive than the actual call to time.monotonic since time.monotonic is implemented as a built-in/cext.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request:

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Black (black --fast homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.
  • Untested files have been added to .coveragerc.

To help with the load of incoming pull requests:

…rectly

This is a small improvment to decrease event loop latency. While the goal is
is to reduce Bluetooth connection time latency, everything using asyncio
is a bit more responsive as a result.
@home-assistant home-assistant bot added cla-signed core small-pr PRs with less than 30 lines. labels Aug 12, 2023
@bdraco bdraco marked this pull request as ready for review August 12, 2023 06:44
@bdraco bdraco requested a review from a team as a code owner August 12, 2023 06:44
homeassistant/runner.py Outdated Show resolved Hide resolved
@bdraco
Copy link
Member Author

bdraco commented Aug 13, 2023

It looks like async_fire_time_changed might be off by a microsecond. Will investigate more tomorrow

@bdraco bdraco marked this pull request as draft August 13, 2023 04:22
@bdraco
Copy link
Member Author

bdraco commented Aug 13, 2023

Looks like it's always been a bit off but it worked before because the run time of the python code was long enough that time moved forward enough between when the time call was made and when the system call/vdso call was made. Now it's too fast and it can fail

@bdraco
Copy link
Member Author

bdraco commented Aug 13, 2023

We need to add clock_resolution to fix async_fire_time_changed

https://github.com/python/cpython/blob/ee40b3e20d9b8d62a9b36b777dff42db1e9049d5/Lib/asyncio/base_events.py#L400

@bdraco
Copy link
Member Author

bdraco commented Aug 13, 2023

freezegun is also a problem since it patches time.monotonic

@bdraco bdraco marked this pull request as ready for review August 13, 2023 06:11
Copy link
Member

@balloob balloob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's give this a try. I would expect any issues to be mainly related to testing as you've experienced in this PR.

Do you think there is an opportunity to upstream this? Or would the JIT work in Py3.12 and beyond make this obsolete?

@balloob balloob merged commit 790c1bc into dev Aug 14, 2023
@balloob balloob deleted the bind_time branch August 14, 2023 00:37
@bdraco
Copy link
Member Author

bdraco commented Aug 14, 2023

Let's give this a try. I would expect any issues to be mainly related to testing as you've experienced in this PR.

Do you think there is an opportunity to upstream this? Or would the JIT work in Py3.12 and beyond make this obsolete?

I've been trying to upstream things that have near 0% risk like the selector changes (all of them are in now). For us changing the test suite a bit usually doesn't cause too many downstream issues, but for cpython itself, it could be a lot bigger issue. This change likely has a much larger benefit for our use-cases vs the general asyncio user since we tend to read a lot (30000 is just what I see on my systems, I've seen users with 100000+ but I think they are outliers) of small packets (esphome, bluetooth, shelly, zeroconf, ssdp, etc). Also, I think the work in Py3.13+ (maybe Py3.14+ actually depending on how things shake out) will make it less impactful.

@bdraco
Copy link
Member Author

bdraco commented Aug 14, 2023

thanks!

@github-actions github-actions bot locked and limited conversation to collaborators Aug 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla-signed core small-pr PRs with less than 30 lines.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants