Pull to refresh

Comments 17

Окончание статьи огонь и жизненное

Чет намногокодил, можно проще. Обосную:

По аналогии с i18n_patterns ставим враппер urlpatterns_transformer на корневой urlpatterns и на старте сервера превращаем стандартный лист в пропатченный, не надо каждый path ручками менять:

# settings.urls.py
urlpatterns = urlpatterns_transformer([
    path("users/<int:user_id>", user_handler),
    path("users/me", me_handler),
]

Уже на этапе патчинга (старта сервера) можно проверять наличие статической составляющей, и ставить в Pattern:

path( .... Pattern=PrefixRoutePattern if idx and idx !=1 else RoutePattern)      

Но и это так себе улучшение, тогда уж третий StaticRoutePattern нужен. Но и это не надо делать, поскольку для префиксов, есть отличное решение с include, померяйте относительно примеров в статье с вот таким вариантом:

#urls = [
#    my_path("users/<int:user_id>", user_handler),
#    my_path("users/me", me_handler),
#]

urlpatterns = [path("users/", include('users.urls')),]

# users.urls.py
urlpatterns = [
    path("<int:user_id>", user_handler),
    path("me", me_handler),
]

Если не нравится новый файл - include принимает и контейнер с url:

class users_urls:
    urlpatterns = [path("int:user_id", user_handler), path("me", me_handler)]

urlpatterns = [path("users/", include(users_urls, 'users_sub_url')),]

Мне кажется, что результат удивит.

Как вариант копания URLdispatch предлагаю посмотреть на сепарирование urls по методам [GET, POST, PATCH], так делают многие фреймворки. Вот тут будет интересный расклад, если PATCH редкий, то он будет срабатывать максимально быстро. Я рассказывал об этом на своем недавнем докладе про "Django FTL", там же линк на репо.

Ну и конечно не плакать надо над 10 секундами ожидания ответа базы, а смотреть, что за ерунда творится. В качестве примера если есть условие с OR c несколькими JOIN - вероятно стоит переехать на Subquery, оказывается, он может работать быстрее, но без explain все равно говорить не о чем - нет информации.

Желаю автору @deliro успехов c Django, там много чего стоит подкручивать. И в первую очередь точно не url.

Эта оптимизация пришла в джанго из сервиса, который мы переписывали с питона на раст, где роутер удалось ускорить в 700 раз (по сравнению с aiohttp'шным — с 300мкс до 450нс в худших случаях). Так что, полностью поддерживаю восьмой пункт:) Но есть большая куча проектов, которые нельзя просто взять и переписать по желанию.

Да уж, наверное проще будет использовать другие реализации виртуальной машины питона)

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

И получается, только входную строку нужно будет разбить. А потом аля дерево по хешам кусков. Как то так. Это просто мысли, не ругайте.

Я уже подумал что-то с роутерами(домашними) на джанге запили, а тут роуТЫ, автор забайтил - реп

Если микросекунды имеют хоть какое-то значение, то, возможно, следует использовать C++/Rust, а не Python+Django.

Мне кажется, для веба go удобнее, но скорее будут использовать язык, который знают разработчики в команде.

Смотря какой веб. Если много бизнес логики, то питон это один из самых лучших языков для её описания. Если огромная нагрузка - то уже другой разговор.

Если много бизнес логики питон напротив один из самых худших вариантов.

Почему и хуже каких, например?

Наверно, по префиксам удобно сделать префиксное дерево, чтобы не проходиться по всем префиксам в цикле

Я бы еще поработал с каждым роутом с переменными: для числа элементов от 100 до (условно) 1млн можно генерировать все варианты при старте приложения до первых клиентов и хранить их в удобной для поиска структуре (например, некий аналог хешмапы с доступом О(1) при отсутствии коллизий).

Ну ладно вы router (читается [рутер] или [раутер]} произносите как [роутер], но маршрут-то всегда был рутом! Такая боль!

Вам когда врач колит инъекцию, вы отказываетесь, пока не принесут инджекцию?

Sign up to leave a comment.