Меня периодически спрашивают, насколько быстр Django. Или как он быстр в сравнении с PHP, Java или Rails. И я не менее периодически затрудняюсь на такой вопрос сразу ответить.

Ответ прямо

С одной стороны, если отвечать на этот вопрос прямо, то Django "очень быстрый". Или, что точнее, "очень мало тормозит", потому что любой фреймворк никогда не ускоряет работу с HTTP, а может только больше или меньше делать лишнего. Здесь у Django и в теории, и в практике все хорошо.

Теоретически его скорость обусловлена, например, такими вещами:

Да и на практике, в общем-то, тоже все хорошо. Есть список маленьких и больших сайтов, которые счастливо работают на Django, а разработчики Django часто повторяют, что их сайты World Online легко переживали даже слэшдоттинг. Да и совместные синтетические тесты Django, RoR и Symphony тоже показывают такую картину.

Ответ по сути

Но все это интересно именно только с одной стороны. На самом деле, по тому, как задается этот самый вопрос — "быстрый ли Django" — часто видно, что человека интересует вопрос другой: "будет ли быстрым мой сайт на Django". А вот это уже — совершенно другое дело.

Я не беру во внимание то, что любое приложение можно просто написать плохо. Я говорю о том, что если вы делаете сайт, который не просто форум, просто wiki или просто блог, то есть не то, что уже было написано тысячей программистов по тысяче раз, то программирование внутри фреймворка рано или поздно заканчивается. Рано или поздно вы начинаете делать специфику приложения, для чего начинаете использовать собственные магические силы, а также призывать сторонние заклинания (библиотеки). И чем дальше, тем меньше в приложении фреймворка, и больше самого приложения. И тормозить оно будет по самым специфичным поводам, и фреймворк тут будет уже ни при чем.

В качестве примера у меня под рукой два моих последних больших проекта, которые делаются с использованием Django: Некий Музыкальный Сервис (про который я уже писал) и Некий Фото-Сайт (про который еще нет).

Пример 1

В музыкальном сервисе основная проблема с производительностью возникла не собственно с сайтом, а с процессом скачивания, который убивал сервер насмерть не потому, что Питон медленный или, там, базу данных я часто пинаю, а потому что каждый процесс скачивания занимал в памяти по 25 МБ неопределенно долгое время, и 4 пользователя с download-менеджерами легко съедали всю память.

Будет еще отдельная статья с подробностями и проблемы, и решения.

Пример 2

Проблема с фото-сайтом была еще экзотичней. Это система заказа печати фотографий, которая предполагается для работы не только в интернете, но и в виде отдельного киоска, в который пользователь загружает файлы не через <input type="file">, а со своей флэшки из цифровика. И в том и в другом случае, для того, чтобы показать человеку превьюшки его собственных фотографий, эти фотографии должны были попасть на сервер. И только когда люди стали приходить с реальными отснятыми сериями, оказалось, что от момента, когда человек воткнул флэшку в дисковод до момента, когда он может хотя бы начать выбирать, что ему напечатать, проходит минут эдак 10, пока все эти мегабайт 300-400 перельются на сервер и там обработаются. И ему трудно понять, почему его компьютер дома показывает все "сразу", а этот — так долго.


Оба эти примера показывают, насколько далеко реальные проблемы реального приложения могут стоять от тех задач, на которые расчитан любой веб-фреймворк: обслуживать короткие запросы на отображение данных из БД в виде HTML. Конечно хорошо, если он делает это быстро. Но это еще далеко не вся песня.

Комментарии: 15

  1. Андрей

    Проблемы с заливкой файла у Django, конечно, есть, но блин веб-интерфейс для киоска - это поганый изврат. А просто переписать на PyQt каком-нибудь таки некошерно? :P Чтоб фотографии показывались сразу, а заливались на сервак уже потом.

  2. Иван Сагалаев

    Проблемы с заливкой файла у Django, конечно, есть

    Заливка файлов средствами Django тут совсем ни при чем: считывание с флешек делалось не через upload-контрол, и браузер там практически не участвовал.

    А проблемы с заливкой файла у Django устраняются патчем, который я давно-давно делал: http://code.djangoproject.com/attachment/ticket/1484/1484.m-r.6.diff

    но блин веб-интерфейс для киоска - это поганый изврат

    Откуда такая однозначная оценка? :-). Вы же не знаете требований заказчика. У решения этого и плюсов немало.

    А просто переписать на PyQt каком-нибудь таки некошерно?

    "Переписать" — вообще не очень кошерное слово, когда идет проект, на который выделены средства, есть план и т.д. Если свободного времени вагон, можно подумать и про "переписать", но тут другой случай.

    Чтоб фотографии показывались сразу, а заливались на сервак уже потом.

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

  3. Efreeti

    Я так понимаю в первом примере было решено с помощью ngnix или подобного "легкого" сервера?

  4. Иван Сагалаев

    Нет :-). Но это была одна из первых попыток решить проблему. Не помогло.

    Да я напишу в ближайшее время, там много чего происходило.

  5. Fabler

    А чем генерация уникальных url'ов и раздача их тем же nginx'ом не устроила? Быстрее приспособленного для отдачи статики сервера ты все равно не сделаешь.

  6. Иван Сагалаев

    В почитай статью, на которую я ссылался. Вкратце: там надо было ограничивать скорость для отдельного юзера (не коннекта), определять успешность закачки и удалять файл сразу после успешного завершения.

  7. Alexander Solovyov

    Кстати, вопрос есть. Не было ли никогда надобности заливать очень большие файлы? А то вот передо мной стоит такая проблема, и не знаю, на чём это дело лучше реализовать.

    Собственно, нужна мне www-морда для ftp://ftp. Взял пока net2ftp, но если я сильно увеличу у пхп максимальный лимит заливаемых файлов - не будет ли мне сервер это убивать?

    Этот самый файлик заливаемый не будет сжирать мою озуху?..

  8. Иван Сагалаев

    Этот самый файлик заливаемый не будет сжирать мою озуху?..

    Теория тут такая. Веб-сервер, когда принимает запрос, отдает его в среду приложения (mod_php, mod_python, fastcgi и т.п.), как только разберет заголовки, то есть сам он файл в память не грузит. Вместо этого он дает среде указатель на поток, что позволяет ей читать данные фактически сразу из сетевого сокета и тут же их обрабатывать.

    Среда уже может делать это по-разному. Django сейчас кушает все в память, но с патчем, который я привел выше, умеет сваливать большие файлы в temp-директорию сразу по мере приема. Судя по вот этому тьюториалу PHP тоже примерно так и делает.

  9. Alexander Solovyov

    А, то есть файл передаётся не в POST'е? А то вот тут у меня как-то затык со знаниями, то я и напрягался - если в POST'е, то это ж в озуху всё бы влетало.

    Ок, ну тогда пойду экспериментировать дальше, спасибо. ;)

  10. Иван Сагалаев

    Мнэ-э... Нет, не так. С точки зрения HTTP — это в любом случае POST-запрос, который выглядит в проводах примерно так:

    POST /some/url/ HTTP/1.1
    Host: myserver.ru
    Content-Type: ...
    Content-Length: ...
    
    ДальшеИдутДанные
    

    То, что PHP раскидывает данные из файловых полей и остальных полей в разные переменные под, названием FILES и POST - это просто дополнительное удобство. Которое, кстати, обусловлено тем, что для передачи файлов браузеры используют другой формат данных. Просто все фреймворки разруливают это без участия пользователя, спасибо им.

    Но чисто протокольно — это все тот же POST-запрос.

  11. Иван Сагалаев

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

  12. Alexander Solovyov

    Ну, насчёт FILES и POST - я даже не был в курсе. %)

    Ну ок, спасибо за разъяснения. А то в инете как-то туго с этим оказалось. :|

  13. alrond

    Привет!
    я тут сравнивал на днях Django и TG.
    Результаты
    на форуме vingrad
    (результаты очень грубые, но дают хоть какое-то представление)
    Если коротко, то Django оказался существенно быстрее Tg.
    Если люди интересуются, значит интерес к разработке возрастает :)))

  14. Иван Сагалаев
        <p>Я там ответил в форуме по методике, продублирую здесь:</p>
    

    Просили замечания по методике:

    • FastCGI сервер запущен в threaded-режиме. Известно, что Питон в тредах работает существенно медленно из-за GIL (Global Interpreter Lock) из-за которого все треды очень часть просто ждут друг-друга, потому что интерпретатором может владеть только кто-то один. Поэтому в юниксах, если есть возможность, серверы с питоновским кодом стоит запускать в prefork-режиме - будет быстрее. Кстати, под Windows ситуация обратная, потому что там создание процесса существенно медленней, чем в юниксах, и там на тредах Питон тормозит, насколько я знаю, все же меньше.

    • Насчет Psyco. Джанговские девелоперы тестировали его, и нашли интересную штуку. На 32-битных системах он действительно дает прирост в производительности. А вот на 64-битных - наоборот, производительность падает. Происходит так из-за того, что под Psyco процессор переключается в 32-битный режим и не использует всех прелестей своей архитектуры. Если все это так, то тот факт, что под Psyco Django таки работал быстрее означает, вероятно, что Linux и Python скомпилены не в 64 битах (несмотря на то, что работает это все на Opteron'е). Это так?

    P.S. Жаль, статья не на блоге! Никаких пингбеков, и чтобы прокомментировать, приходится проходить регистрацию...

  15. Alexander Solovyov

    Насчёт тредов и Windows'а хотелось бы заметить:

    и там на тредах Питон тормозит, насколько я знаю, все же меньше.

    В винде реально сами треды сделаны хорошо. А в Линухе - плохо. Во FreeBSD - еще хуже. Вот в Solaris'e - неплохо, в принципе, но, ЕМНИП, всё же хуже, чем в Винде.

    В то же время да, традиционно в никсах цена форка очень низка.

Добавить комментарий