Как стать автором
Обновить

Самый быстрый фреймворк на Диком Западе: ускоряем Django-rest-framework вместе с Rust

Уровень сложностиСредний
Время на прочтение15 мин
Количество просмотров7K
Всего голосов 22: ↑22 и ↓0+28
Комментарии17

Комментарии 17

На php надо было писать :)

Чтобы к медленному выполнению добавились ещё и неуловимые баги из-за слабой типизации?)

Есть возможность включить строгую типизацию

Не понял где именно была просадка производительности в старом решении.

Было бы интересно посмотреть на эффект values до использования Rust. Я как-то сделал мега оптимизацию вызова ендпоинта по памяти просто не загружая в память то, что не использовалось.

Привет, по сути основная просадка заключается в том, как собирается древовидная структура (маппинг по id сначала дерева съютов и затем маппинг кейсов к этим съютам), нам нужно отдать все данные разом, и более того этот endpoint отвечает за поиск и должен быть сильно отзывчивым, чтобы фронт мог подгрузить дерево выбора, и условие в том что фронт мы менять не можем, DRF сериализатор при сборе всех данных которые нам нужны использует related managers, и это получается сильно дорого, так как это все получение ORM объектов и их cpu-bound сериализация, если мы исключим Rust из уравнения и сделаем в python тоже самое, что мы отдали на выполнение Rust-у c использованием values, то получим результат быстрее, чем DRF, но он все равно будет хуже чем у раста потому что все равно остается cpu-bound задача на циклах, в самом большом проекте, который у нас есть, решение на values и простых циклах в python мы получаем +-8 секунд, с Rust результат меньше секунды.

а я всё равно не понял, где там циклы. максимум -- поиск по индексу там должен быть, с ним 100к небольших объектов сериализовать должно быть реально за секунду.

Интуитивно кажется что так и есть.

@RomanKabaev а есть вомзожность пошарить, что подаётся на вход и что получается на выходе у rust библиотеки?

Я бы попробовал выжать из Питона пару секунд времени.

Привет, возможность скинуть данные нет, но есть подозрение что я допустил ошибку когда сравнивал перформанс, в детали пока вдаваться не буду, сейчас большая загрузка на проектах, постараюсь вернуться с развернутым ответом в ближайшую неделю/на следующей неделе, как только протестирую все еще раз.

ну как? :)

А если сравнить с версией 3.12, какой прирост по производительности будет?

На момент реализации, часть библиотек не работала с 3.12, не знаю как ситуация обстоит сейчас, поэтому этот вариант не рассматривался

Ещё б ржавый код каким-нибудь clippy обработать, а то местами оно выглядит несколько странно и неконсистентно, в сравнении с тем же питоном - приколы типа x.borrow().clone() пополам с Rc::clone().

Я не Rust разработчик и про лучшие практики знаю мало, но судя по этому правилу такое написание рекомендуется для Ref counter-ов https://rust-lang.github.io/rust-clippy/master/index.html#/clone_on_ref_ptr

Я понял, что ошибся. Думал что вы в первом случае тоже ссылку копируете, но копируются данные. С другой стороны не очень понятно зачем их клонировать, когда сами данные кажется достаточно локальные и можно целиком отдать их в чужое владение, просто развернув их из умного указателя. Но тут вам определённо виднее.

Очень странные дела. А точно нельзя было языком SQL решить кейс? Ну из плоского сделать дерево - вроде умеет.

Впервые вижу чтобы были проблемы json отдать в питоне. Хотя мы FastAPI используем и тоже orjson, ijson или как его там. Всё быстро дампиться в json строку.

Но статья прикольная. Плагин на Rust - это мощно

Присоединяйтесь к бесплатному курсу по Rust на платформе Stepik :)

У меня была подобная задача ровно 10 лет назад. Выкрутился тем, что написал хранимку на pl/v8 (pl/upython на AWS нельзя использовать, т.к. он untrusted). Причём сборка json была выполнена с помощью склейки частей. Результат был порядка 50Mb.

Но у этой байки счастливый финал. За три месяца мы отрефакторили архитектуру и выбросили этот костыль.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий