classification
Title: Add dedicated slot for sending values
Type: performance Stage: resolved
Components: Interpreter Core Versions: Python 3.10
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: asvetlov, miss-islington, v2m, yselivanov
Priority: normal Keywords: patch

Created on 2020-10-19 19:38 by v2m, last changed 2020-11-18 23:39 by yselivanov. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 22780 merged v2m, 2020-10-19 19:39
PR 23237 merged asvetlov, 2020-11-11 15:02
PR 23374 merged v2m, 2020-11-18 18:41
Messages (12)
msg378999 - (view) Author: Vladimir Matveev (v2m) * Date: 2020-10-19 19:38
https://bugs.python.org/issue41756 has introduced PyIter_Send as a common entrypoint for sending values however currently fast path that does not use StopIteration exception is only available for generators/coroutines. It would be quite nice if this machinery was extensible and other types (both internal and 3rd party) could opt-in into using exception-free way of returning values without needing to update the implementation of PyIter_Send. One way of solving this is adding a new slot with a signature that matches PyIter_Send. With it:
- it should be possible to implement this slot for coroutines/generators and remove  special casing for them  in PyIter_Send
- provide implementation for this slot for internal types (i.e. FutureIter in _asynciomodule.c) - results of this experiment can be found below
- enable external native extensions to provide efficient implementation of coroutines (i.e.  Cython could benefit from it)

Microbenchmark to demonstrate the difference of accessing the value of fulfiled Future without and with dedicated slot:
```
import asyncio
import time

N = 100000000

async def run():
    fut = asyncio.Future()
    fut.set_result(42)

    t0 = time.time()
    for _ in range(N):
        await fut
    t1 = time.time()
    print(f"Time: {t1 - t0} s")

asyncio.run(run())
```
Time: 8.365560054779053 s - without the slot
Time: 5.799655914306641 s - with the  slot
msg380706 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2020-11-10 20:10
New changeset 1e996c3a3b51e9c6f1f4cea8a6dbcf3bcb865060 by Vladimir Matveev in branch 'master':
bpo-42085: Introduce dedicated entry in PyAsyncMethods for sending values (#22780)
https://github.com/python/cpython/commit/1e996c3a3b51e9c6f1f4cea8a6dbcf3bcb865060
msg380708 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2020-11-10 20:10
Vladimir, please do a follow up PR documenting Py_TPFLAGS_HAVE_AM_SEND.
msg380750 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-11-11 11:22
> New changeset 1e996c3a3b51e9c6f1f4cea8a6dbcf3bcb865060 by Vladimir Matveev in branch 'master':

This change introduced big reference leaks:

4 tests failed:
    test_asyncgen test_asyncio test_coroutines test_unittest

Example:

$ ./python -m test test_asyncgen -R 3:3 -m test.test_asyncgen.AsyncGenAsyncioTest.test_async_gen_asyncio_03
(...)
test_asyncgen leaked [63, 63, 63] references, sum=189
(...)

Please fix the leak, or revert if nobody is avaible to fix it:
https://pythondev.readthedocs.io/ci.html#revert-on-fail
msg380763 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2020-11-11 14:07
Investigating. The test leaks a future instance.
msg380765 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2020-11-11 15:07
PR for the fix is created: https://github.com/python/cpython/pull/23237
msg380770 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-11-11 16:46
commit cda99b4022daa08ac74b0420e9903cce883d91c6 (HEAD -> master, upstream/master)
Author: Andrew Svetlov <andrew.svetlov@gmail.com>
Date:   Wed Nov 11 17:48:53 2020 +0200

    Fix memory leak introduced by GH-22780 (GH-23237)
msg380772 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-11-11 16:50
Thanks! The change fixed the leak:

$ ./python -m test -j0 -R 3:3 test_asyncgen test_coroutines test_unittest # test_asyncio 
(...)
Tests result: SUCCESS

I didn't run test_asyncio because the test is too slow.
msg380777 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2020-11-11 17:20
Thank you Victor for the report!
msg381369 - (view) Author: miss-islington (miss-islington) Date: 2020-11-18 18:58
New changeset 7c9487ded487f304c2906698c52f0815b92cbeb6 by Vladimir Matveev in branch 'master':
bpo-42085: Add documentation for Py_TPFLAGS_HAVE_AM_SEND (GH-23374)
https://github.com/python/cpython/commit/7c9487ded487f304c2906698c52f0815b92cbeb6
msg381375 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2020-11-18 22:08
Is anything left to do?
msg381381 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2020-11-18 23:39
> Is anything left to do?

I think we can close this now.
History
Date User Action Args
2020-11-18 23:39:19yselivanovsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2020-11-18 23:39:10yselivanovsetmessages: + msg381381
2020-11-18 22:08:09asvetlovsetmessages: + msg381375
2020-11-18 21:38:05vstinnersetnosy: - vstinner
2020-11-18 18:58:46miss-islingtonsetnosy: + miss-islington
messages: + msg381369
2020-11-18 18:41:18v2msetpull_requests: + pull_request22267
2020-11-11 17:20:30asvetlovsetmessages: + msg380777
2020-11-11 16:50:35vstinnersetmessages: + msg380772
2020-11-11 16:46:56vstinnersetmessages: + msg380770
2020-11-11 15:07:38asvetlovsetmessages: + msg380765
2020-11-11 15:02:07asvetlovsetpull_requests: + pull_request22135
2020-11-11 14:07:59asvetlovsetmessages: + msg380763
2020-11-11 11:22:15vstinnersetnosy: + vstinner
messages: + msg380750
2020-11-10 20:10:52yselivanovsetmessages: + msg380708
2020-11-10 20:10:03yselivanovsetmessages: + msg380706
2020-10-21 03:23:56terry.reedysetnosy: + asvetlov, yselivanov
2020-10-20 18:04:19v2msettype: performance
2020-10-19 19:39:12v2msetkeywords: + patch
stage: patch review
pull_requests: + pull_request21739
2020-10-19 19:38:16v2mcreate