{"action":"created","issue":{"url":"https://api.github.com/repos/micropython/micropython/issues/2622","repository_url":"https://api.github.com/repos/micropython/micropython","labels_url":"https://api.github.com/repos/micropython/micropython/issues/2622/labels{/name}","comments_url":"https://api.github.com/repos/micropython/micropython/issues/2622/comments","events_url":"https://api.github.com/repos/micropython/micropython/issues/2622/events","html_url":"https://github.com/micropython/micropython/issues/2622","id":188903177,"number":2622,"title":"Ideas on optimizing uasyncio","user":{"login":"pfalcon","id":500451,"avatar_url":"https://avatars.githubusercontent.com/u/500451?v=3","gravatar_id":"","url":"https://api.github.com/users/pfalcon","html_url":"https://github.com/pfalcon","followers_url":"https://api.github.com/users/pfalcon/followers","following_url":"https://api.github.com/users/pfalcon/following{/other_user}","gists_url":"https://api.github.com/users/pfalcon/gists{/gist_id}","starred_url":"https://api.github.com/users/pfalcon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pfalcon/subscriptions","organizations_url":"https://api.github.com/users/pfalcon/orgs","repos_url":"https://api.github.com/users/pfalcon/repos","events_url":"https://api.github.com/users/pfalcon/events{/privacy}","received_events_url":"https://api.github.com/users/pfalcon/received_events","type":"User","site_admin":false},"labels":[{"id":73395454,"url":"https://api.github.com/repos/micropython/micropython/labels/rfc","name":"rfc","color":"FF66CC","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-11-12T09:52:59Z","updated_at":"2016-11-12T15:55:40Z","closed_at":null,"body":"With https://github.com/micropython/micropython/issues/2219 landed and uasyncio updated to it (in a branch), discuss further ideas for improvement (many would require changes to uPy for \"optimizations\"), so ticket is here:\r\n\r\n* A thought: millisecond-perfect tasks scheduling requires working with times on microsecond level, and in a smart way. E.g. there's no warranty that after sleep_ms(20) ticks_ms() will be 20 late (can be 21, on funny systems can be 19).\r\n* The aim should be achieving memalloc-free running of non-recursive coroutines. The current culprit is actually packing task entries into a queue, which requires creating a tuple. Thus, uasyncio queue should be optimized, and now that #2219 has landed, the next obvious is step is to revert it and redo as an adhoc queue. That all was expected long ago, but seeing's believing.\r\n* yield from's aka await's from cosubroutines still will pose a problem, each such cocall will cause allocation. Here, we should try to exploit paradigmatic duality of closures and objects - they both approach storing internal state from different sides. And indeed, yield from works not with just coros, but with objects, on which it will call `__next__()`. However, we still don't want to allocate object either, what I have in mind is having and async method of an object with a special call semantics, where it's passed its object and can yield (unlike `__next__`??). This is not achievable in Python, but we'll definitely need ability to code coroutines in C. So, the idea is to have:\r\n~~~\r\nline = await stream.readline()\r\n~~~\r\nto have following call semantics:\r\n~~~\r\nStreamClass.readline__next__(stream)\r\n~~~\r\n\r\nI.e. there should be special methods in an object, await'ing which just calls them as a normal method, but allowing it to indicate that it yields in addition to just returning a value. The problem comes with handling arguments, e.g.\r\n\r\n~~~\r\nline = await stream.readline(512)\r\n~~~\r\n\r\nThat either will require special compiler treatment to transform that to:\r\n\r\n~~~\r\nStreamClass.readline__next__(stream, 512)\r\n~~~\r\n\r\nOr, given that coroutine semantics is strictly sequential, i.e. it's an error to call .readline() coroutine on the same object while another call is active, i.e. there's nor reenterability problem, we can do it like:\r\n\r\n~~~\r\nstream.last_args = (512,)\r\nStreamClass.readline__next__(stream)\r\n~~~\r\n\r\nThis can be completely implemented on object level, i.e. `__call__` on special comethod stores passed args and returns self, then `__next__` on it executes it.\r\n"},"comment":{"url":"https://api.github.com/repos/micropython/micropython/issues/comments/260130041","html_url":"https://github.com/micropython/micropython/issues/2622#issuecomment-260130041","issue_url":"https://api.github.com/repos/micropython/micropython/issues/2622","id":260130041,"user":{"login":"roger-","id":1389709,"avatar_url":"https://avatars.githubusercontent.com/u/1389709?v=3","gravatar_id":"","url":"https://api.github.com/users/roger-","html_url":"https://github.com/roger-","followers_url":"https://api.github.com/users/roger-/followers","following_url":"https://api.github.com/users/roger-/following{/other_user}","gists_url":"https://api.github.com/users/roger-/gists{/gist_id}","starred_url":"https://api.github.com/users/roger-/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/roger-/subscriptions","organizations_url":"https://api.github.com/users/roger-/orgs","repos_url":"https://api.github.com/users/roger-/repos","events_url":"https://api.github.com/users/roger-/events{/privacy}","received_events_url":"https://api.github.com/users/roger-/received_events","type":"User","site_admin":false},"created_at":"2016-11-12T15:55:40Z","updated_at":"2016-11-12T15:55:40Z","body":"> Sorry, can't imagine anything more useless than that.\r\n\r\nWorks for most people. \r\n\r\nMy point is that people know sockets and tend to be confused by asyncio (I \"learned\" asyncio a year ago but now I'd struggle to recall how to write a UDP server if you asked). Making async work seamlessly by basically dropping in a `await` would make it easy. Of course having a file-like stream API is good too, but they don't have to be mutually exclusive (just like in curio). \r\n\r\n"}}
{"actor":{"display_login":"roger-"}}