Comments 13
Меня это интересует, но мне хотелось бы исполнять async Rust. Оценил бы, если бы ты рассмотрел этот вариант.
Async Rust живет в неком рантайме внутри Rust. Вы можете запустить рантайм в треде, например, и отправлять туда задачи. В общем, вопрос сильно обширный, но вот это может вам подать идею:
https://github.com/insight-platform/RocksQ/blob/main/queue_rs/src/nonblocking.rs
ну и соответствующую реализацию в Python смотрите. В целом async Python и async Rust никак не связаны. Если вы умеете взаимодействовать с async рантаймом из Rust, то проблем быть не должно.
Вот прям пример с async кодом у себя нашел: https://github.com/insight-platform/savant-rs/blob/main/etcd_dynamic_state/src/parameter_storage.rs
Как это мапится в Python - ищите в проекте.
Недавно вышел доклад про использовании асинхронного Rust в чужом окружении, довольно доходчиво описываются возникающие проблемы. Что самое интересное, передача данных через unix сокеты оказывается легче и быстрее (!) , чем маршаллинг через FFI. Чужая платформа в данном случае это JVM, но для питона проблемы будут +- те же. Рекомендую глянуть в-общем: https://youtu.be/z3tpB94VKwU
Готов спорить, что я найду группы операций, когда это будте не выгодно:
Время алгоритма существенно меньше времени упаковки данных и их распаковки с помощью Protobuf, например, чтобы в сокет отправить.
Размер данных для пересылки большой. Например, сырые RGBA фреймы. Я лично проверял, что через unix-сокет пересылка занимает больше времени, чем через память.
Не знаю, зачем бы вообще городить такие костыли - недавно переписывали код индусов, которые вместо байндингов Python к SDK на C++ пытались данные передавать через Unix-сокеты. Угадайте что у них получилось?
Да и сами подумайте, не знаю как Java, но в Python половина всего на FFI. Что-то никто не кинулся переписывать это на доменные сокеты Unix.
Угадайте что у них получилось?
Тормозное нечитаемое поделие? ?
В целом я соглашусь, что в случае unix-сокетов происходит копирование данных из адресного пространства одного процесса в адресное пространство другого. Даже если это сверхоптимизировать, от копирования не уйти, а в случаее FFI можно сделать передачу просто по ссылке, что будет всегда быстрее при больших массивах.
Какой конкретный вариант использования был у докладчика я не знаю, но скорее всего у него случай, далёкий от указанных вами.
Пользуясь случаем, поблагодарю за статью, весьма ценная крупица знания.
Насчёт unsafe
и transmute
: семантичнее было бы это делать с помощью derive
автоматической реализации From
. С точки зрения кода это чище и красивее (и короче): просто пишем let x: W = s.into()
, а на выходе то же самое (то есть эффективное ничего). Или у предложенного способа с трансмутацией есть какие-то иные неочевидные преимущества?
Так тоже можно, конечно, но transmute делает это без перевыделения памяти и создания нового объекта (inplace).
Насколько я понимаю, move-семантика в Rust как раз это и обеспечивает: мы просто даём фрагменту памяти другое имя. Во всяком случае, в godbolt мне не удалось увидеть перемещение данных в памяти при использовании into
вместо transmute
, даже с итерацией по вектору они скомпилировались в одинаковый код.
Возможно, что так и будет :), я не спорю, потому что не проверял.
По-умолчанию, From не позволяет делать derive:

Но есть такие крейты:
Да, для вывода имплементации From
можно воспользоваться одним из этих крейтов. Ещё хочу обратить внимание на статью, где автор избавляется от unsafe, одновременно делая код более выразительным и не снижая (а иногда и повышая) производительность
Познавательная статья. Сам сейчас в процессе написания первой библиотеки на Rust для Python. Рад, что многих проблем удалось избежать уже на старте. По большинству пунктов приняты те же решения.
Библиотека у меня реализует L2 протокол, в связи с этим вопрос про Vec<u8>. При каких размерах начинается замедление? В моем случае один фрейм не более 250 байт. Аргумент Vec<u8>, полученный из python всегда оборачивается в Bytes::from(...) и далее в Rust я работаю с Bytes. Правильно понимаю, что замедление именно на передаче аргумента?
Как я проектирую и разрабатываю расширения Python на Rust