Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Optimize Task._step and Task._wakeup #289

Closed
wants to merge 1 commit into from
Closed

Conversation

1st1
Copy link
Member

@1st1 1st1 commented Nov 13, 2015

I found a way to monkey-patch asyncio.Future and make it compatible with uvloop (see #282 for details).

This PR will significantly improve futures performance in uvloop (~10-15%) while we wait till 3.5.2. In 3.5.2, instead of adding AbstractFuture, or using ABCMeta, I propose to directly incorporate my C accelerator in asyncio -- that's probably the simplest solution.

This change is 100% backwards compatible -- it's a pure optimization. Please consider accepting this before 3.5.1.

@@ -247,7 +247,8 @@ def _step(self, value=None, exc=None):
self.set_exception(exc)
raise
else:
if isinstance(result, futures.Future):
# Use duck-typing here. `isinstance(result, Future)` is slow.
if hasattr(result, 'add_done_callback'):
Copy link
Member

Choose a reason for hiding this comment

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

I would recommend checking for a method that concurrent.futures.Future does not have. Or add a new class attribute specifically for the purpose of this test.

(I'm also still unclear on what makes isistance() slow. Do you have a microbenchmark for that?)

Copy link
Member Author

Choose a reason for hiding this comment

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

On a macro benchmark the difference is about 4%. Let me come up with a micro benchmark...

Copy link
Member Author

Choose a reason for hiding this comment

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

On a micro benchmark the difference is about 4% too.

After giving this some thought, I think we can keep this isinstance, since, quoting you, "[...] checking for a method that concurrent.futures.Future does not have" I don't like -- feels too hacky.

Can I merge the second change _step(value, None) -> _step(), though?

Copy link
Member

Choose a reason for hiding this comment

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

@1st1
Copy link
Member Author

1st1 commented Nov 16, 2015

@gvanrossum So what do you think about this PR?

@gvanrossum
Copy link
Member

OK, you can commit the change to the _step() call.

1st1 added a commit that referenced this pull request Nov 16, 2015
@1st1
Copy link
Member Author

1st1 commented Nov 16, 2015

Thanks a lot for the review! Closing the PR.

@1st1 1st1 closed this Nov 16, 2015
akheron pushed a commit to akheron/cpython that referenced this pull request Nov 17, 2015
See python/asyncio#289 for details.

--HG--
branch : 3.4
ajdavis added a commit to mongodb/motor that referenced this pull request Mar 6, 2016
See python/asyncio#289

After this optimization to asyncio, my "yieldable()" wrapper no longer
returns the Future's result, so I have to retrieve the result in a
separate step.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants