Да, Python медленный, но меня это не волнует
Nuances of programmingПеревод статьи Nick Humrich: Yes, Python is Slow, and I Don’t Care

Я возьму перерыв от обсуждения темы AsyncIo в Python, чтобы поговорить об одной важной вещи - скорости работы Python. Для тех, кто не знает, я - фанат Python и поэтому использую его везде, где можно. Но у этого языка есть проблема, на которую жалуются очень много людей: он медленный. Из-за этого некоторые пользователи даже не хотят попробовать в нём работать.
Скорость не имеет значения
Раньше тот факт, что программа долго выполнялась, был нормальным явлением. Процессоры были дорогими, память была дорогой. Время работы программы было очень важным фактором. Также компьютеры и электричество, которое их питало, было очень дорогими. Оптимизация этих процессов была проведена с помощью нетленного закона бизнеса:

Так исторически сложилось, что самым дорогим ресурсом было время работы компьютера. Это то, что в первую очередь помогает изучать информатику, направленную на эффективность различных алгоритмов. Однако в наши дни это уже не так, потому что материалы подешевели. Серьезно подешевели. Время загрузки уже ваш не самый дорогой ресурс. Сейчас самый дорогой ресурс всех компаний - время их работников. Или, другими словами, Вас. Гораздо важнее выполнить задание, чем выполнить его быстро. На самом деле это настолько важно, что я приведу цитату (для тех, кто просто пролистывает):

Вы можете сказать: "Моя компания заботится о скорости, я работаю над веб-приложением, и все отклики о нем должны быть незамедлительными". Или: "У нас есть недовольные клиенты, которые считают, что наше приложение слишком медленное". Не поймите меня неправильно, я не пытаюсь сказать, что скорость совсем не имеет значения, я лишь хочу сказать, что на данный момент это не самый дорогой ресурс.

Скорость - единственное, что имеет значение
Когда вы говорите скорость в контексте программирования, вы скорее всего подразумеваете производительность вашего центрального процессора. Когда генеральный директор говорит скорость, он имеет в виду скорость развития бизнеса. Наиболее важным является время выхода на рынок. В конечном счете, скорость работы вашего продукта или веб-приложения не так важна. Также неважно, на каком языке программирования это было написано. Но все же есть одна вещь, которая заставит вашу компанию выжить или умереть на рынке. Я говорю не только об идее стартапа, но и о том, сколько времени вам потребуется, чтобы заработать первые деньги, я говорю о времени доставки товара от разработчиков компании до клиентов. Единственный способ остаться в этом бизнесе на плаву - развиваться быстрее конкурентов. Не имеет значения, сколько хороших идей вы придумали, если ваши конкуренты идут на дно. Вы должны быть первыми на рынке, или по крайне мере не отставать. Если вы затормозите - пойдете ко дну.

Случаи микросервисов
Крупные компании, такие как Amazon, Google или Netflix, понимают важность быстрого развития. Они специально строят свой бизнес так, чтобы быстро вводить инновации. Микросервисы помогают им в этом. Эта статья не имеет никакого отношения к тому, следует ли вам строить на них свою архитектуру, но, по крайней мере, согласитесь с тем, что Amazon и Google должны их использовать.

Микросервисы везде
Микросервисы медленны по своей сути. Сама их концепция заключается в том, чтобы использовать сетевые вызовы. Иными словами, вместо вызова функции вы отправляетесь гулять по сети. Что может быть хуже с точки зрения производительности? Сетевые вызовы очень медленны по сравнению с тактами процессора. Однако, большие компании по-прежнему предпочитают строить архитектуру на основе микросервисов. Я действительно не знаю, что может быть медленнее. Самый большой минус такого подхода - производительность, в то время как плюсом будет время выхода на рынок. Создавая команды вокруг небольших проектов, компания может развиваться и вводить инновации намного быстрее. Мы видим, что даже очень крупные компании заботятся о времени выхода на рынок, а не только о стартапах.
Процессор больше не является проблемным местом

Если вы пишете сетевые приложения, такие как веб-сервер, скорее всего, процессор не является проблемным местом вашего приложения. В процессе обработки запроса будет сделано несколько сетевых обращений, например, к базе данных или кешу. Эти сервера могут быть бесконечно быстрыми, но всё упрётся в скорость передачи данных по сети.
В конечном счёте то, что python медленный, уже не имеет значения. Скорость языка (или процессорного времени) почти никогда не является проблемой. Google описал это в своём исследовании. А там, между прочим, говорится о разработке высокопроизводительной системы. В заключении приходят к следующему выводу:

Другими словами:

А что если процессор стал проблемой?
Вы можете говорить: "Всё это прекрасно, но что, если CPU становится проблемным местом, что начинает сказываться на производительности?" или "Язык x менее требователен к железу, нежели y". Всё это может быть правдой. Замечательная вещь относительно веб-серверов это то, что вы можете балансировать нагрузку практически бесконечно. Другими словами, для того чтобы всё работало лучше, добавьте больше серверов. Безусловно Python более требователен к железу, нежели С. Просто добавьте больше серверов. Они дешевле Вашего времени, поверьте.

Что же в итоге, Python быстрый?
На протяжении всей статьи я говорил, что самое важное - время разработчика. Но вопрос все ещё не закрылся: быстрее ли Python языка X когда речь заходит о времени разработки проекта? Как бы смешно это не было, но я, Google, и еще несколько компаний могут Вам с уверенностью сказать, что Python очень продуктивен. Он даёт сконцентрироваться на главном, оставляя мелочи скрытыми. Вы можете и не согласиться с моим мнением, но давайте все же рассмотрим несколько примеров.
По большей части споры вокруг производительности Python сводятся к одной теме - динамической или статической типизации. Я думаю всем известно, что типизированные языки менее продуктивны. Что касается Python, то есть неплохой отчет, в котором показывается сколько времени потребовалось, чтобы написать код для обработки строк на разных языках.

Опираясь на это исследование, можно заметить, что Python в три раза продуктивнее Java. Многие другие языки, представленные в таблице, показывают похожий результат. Rosetta Code провёл внушительное исследование различий изучения языков программирования. В статье они сравнивают Python с другими интерпретируемыми языками и заявляют:

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

Но что, если скорость действительно важна?

Опираясь на вышеизложенный текст Вы могли подумать, что оптимизация и скорость выполнения программы вообще не имеют значения. Во многих случаях это не так. Например, у вас есть веб-приложение и некоторый endpoint, который уж очень тормозит. У вас могут быть даже определённые требования на этот счёт. Наш пример строится на некоторых предположениях:
1. Есть некоторый endpoint, который выполняется медленно
2. Есть некоторые метрики, определяющие насколько медленными может быть обработка запросов
Мы не будем заниматься микро-оптимизацией всего приложения. Всё должно быть «достаточно быстро». Ваши пользователи могут заметить, если обработка запроса занимает секунды, но они никогда не заметят разницу между 35 мс и 25 мс. Вам нужно лишь сделать приложение «достаточно хорошим». Должен заметить, что есть некоторые приложения, которые обрабатывают данные в реальном времени, которые нуждаются в микро-оптимизации, и каждая миллисекунда имеет значение. Но это скорее исключение, чем правило. Чтобы понять как оптимизировать, мы должны сначала понять что именно надо оптимизировать:

Если оптимизация не устраняет проблемное место, вы впустую тратите время, а не решаете реальную проблему. Вам не следует продолжать разработку, пока не устраните все неполадки. Если вы пытаетесь оптимизировать что-то непонятное, результат вас вряд ли обрадует. Это называется «преждевременной оптимизацией» - улучшение производительности, не понимая где находится проблема. Дональду Кнуту часто приписывают данную цитату, хоть он и утверждает, что это не его цитата:

Более полная цитата:

Другими словами, в этой цитате говорится, что в основном вам не следует думать об оптимизации. Код и так неплох. В случае, если это не так, нужно изменить не более 3%. Вас никто не похвалит за то, что вы увеличили скорость обработки запроса на несколько наносекунд. Оптимизируйте то, что может быть заметно пользователям.
Преждевременная оптимизация, как правило, заключается в вызове более быстрых методов или использовании специфичных структур данных из-за их внутренней реализации. В университете нас учили, что если два алгоритма имеют одну асимптотику Big-O, то они эквивалентны. Даже если один из них в 2 раза медленнее. Компьютеры сейчас настолько быстры, что вычислительную сложность пора измерять с применением большого количества данных. То есть, если у вас есть две функции O(log n), но одна в два раза медленнее другой, то это не имеет большого значения. По мере увеличения размера данных они обе начинают показывать примерно одно и то же время выполнения. Вот почему преждевременная оптимизация - это корень всего зла. Это тратит наше время и практически никогда не помогает нашей общей производительности.
В терминах Big-O все языки программирования имеют сложность O(n), где n — кол-во строк кода или инструкций. Не имеет значения, насколько медленным будет язык или его виртуальная машина - все они имеют общую асимптоту. В соответствии с этим рассуждением можно сказать, что «быстрый» язык программирования всего лишь преждевременно оптимизированный, причём непонятно по каким метрикам


Оптимизация в Python
Одна из моих любимых фишек Python - оптимизация части кода. Допустим, у вас есть метод на Python, который вы считаете слабым местом. Вы уже оптимизировали его несколько раз и в итоге пришли к выводу, что час Python является слабым местом. Он может вызывать код на С, значит, вы можете переписать этот метод на С, чтобы уменьшить проблему с производительностью. Вы без проблем сможете использовать этот метод вкупе с остальным кодом. Это позволяет писать хорошо оптимизированные методы проблемных мест на любом языке, который компилирует ассемблер. Это позволяет большую часть времени оставаться в Python и использовать низкоуровневые языки только тогда, когда Вам это действительно необходимо.
Также существует язык Cython, он является улучшенной версией Python. Он представляет из себя некую смесь Python и С. Любой код на Python можно запустить на Cython. Вы можете смешивать С с Pyhon без всяких проблем. Используя Cython, вы получаете прирост производительности только в проблемном месте, не переписывая весь остальной код. Так делает, например, EVE Online.

Эта MMoRPG использует только Python и Cython для всего стека, проводя оптимизацию только там, где это требуется. Кроме того, есть и другие способы. Например, PyPy - реализация JIT Python, которая может дать вам значительный прирост скорости во время выполнения долгоживущих приложений (например, веб-сервера), просто путем замены CPython (реализация по умолчанию) на PyPy.

Итак, подведем итоги:
- Оптимизируйте использование самого дорогого ресурса - то есть вас, а не компьютера;
- Выбирайте язык/фреймворк/архитектуру, которая позволяет вам разрабатывать продукты как можно быстрее (такой как Python). Не стоит выбирать язык программирования лишь потому, что программы на нём работают быстро;
- Если у вас проблемы с производительностью - определите, где именно;
- И, скорее всего, это не ресурсы процессора или Python;
- Если это всё же Python (и вы уже оптимизировали алгоритм), реализуйте проблемное место на Cython/C;
- И побыстрее возвращайтесь к основной работе.
Спасибо за внимание!