по очереди продолжать асинхронные функции, после выполнения вложенных асинхронных функций?
Например в контексте вложенных g(f(x)) при выполнении f(x), делать resume g(f(x))?
Вроде же реализация экзекутора — это не часть раста, а отдана на откуп библиотекам (tokio, async_std, etc.)?
Потому что так проще сохранять стейт, afaik continuation-based асинк без гц достаточно замороченно делать. Плюс в poll-based можно всё на статических вызовах zero cost сделать, а с continuation тебе так или иначе придётся функции по указателям выполнять.
As a nice side effect: в раст асинке стэк трейс имеет смысл
А в каком плане zero cost? я не совсем понимаю
В том плане, что статический вызов очевиден компилятору и он может его оптимизировать как хочет. Например заинлайнить. Ты за него (почти) не платишь. Динамик диспатч относительно сильно более дорогой
Хм а в каких языках сделано иначе и при этом эффективнее?
хз, но теоритически это не будет эффективнее?
То что там метод называется пулл не значит что там постоянно что-то опрашивает. Там вейкер пробуждает когда задача выполнена
нет, ты на пуш-бейзд футурах же такой же полноценный (растовый) асинк можешь реализовать
В плане что одна футура которая вызывает 10 футур через асинк авейт и другая где все накопипащено в тело дадут один перформанс. Если сравнить в шарповыми футурами или жсовыми промисами то там каждый авейт делается на отдельную футуру которая будет ллоцированна и дергаться отдельно
http://aturon.github.io/tech/2016/09/07/futures-design/
В каком смысле накопипащенно в тело?
возьмем жс: const foo = async () => { await do1(); await do2(): } const bar = async () => { await do3(); await do4(): } const baz = async () => { await foo(); await bar(): } тут футуры foo и bar будут сущестовать реально - они будут аллоцированны, и будут дергать resolve по выполнению. Теперь если мы возьмем раст то async fn foo() { do1().await; do2.await; } async fn bar() { do3().await; do4.await; } async fn baz() { foo().await; bar.await; } Оно вместо того чтобы реально дергать в рантайме как тут написано перепишет в стейтмашину вида async fn baz() { do1().await; do2.await; do3().await; do4.await;} Имеет право оно сделать именно из-за модели поллинга, с комплишном так сделать не получится насколько я помню. В итоге никаких аллокаций и лишних прыжков. Другой плюс это отмена пендинг операций - с комплишном это геморрой с передачей всяких CancellationToken'ов которые нужно мониторить и т.п. В расте эе просто делаешь drop(future) и она автоматом отменится. Ну короч почитай ссылку что я кидал, там все написано
не очень понятно написано если честно. Опять проблема double linked структур в расте.
Как будто в расте канцелоятион токены не нужны
можно просто дроп, если ты эту операцию не в отдельном треде пустил
Ну ок. А что именно в плане комбинаторов? Они же по идеи будут не очень оптимальны?
любая комбинация авейтов любой вложенности по сути с компилируется в единственную стейт машину с одним гигантским свитчем на всё что должно произойти за время выполнения всей футуры
Обсуждают сегодня