CPython особенно медленный, потому что у него нет оптимизатора Just in Time (поскольку он является эталонной реализацией и в некоторых случаях выбирает простоту по производительности). Unladen Swallow - это проект, который добавляет JIT в LLVM в CPython и достигает огромных ускорений. Возможно, что Jython и IronPython намного быстрее, чем CPython, а также поддерживаются сильно оптимизированными виртуальными машинами (JVM и .NET CLR).
Одна вещь, которая, возможно, оставит Python медленнее, однако, заключается в том, что это динамически типизируется, и есть тонны поиска для каждого доступа к атрибуту.
Например, вызов f
для объекта A
приведет к возможным поискам в __dict__
, вызовам __getattr__
и т. д. затем, наконец, вызовите __call__
на вызываемом объекте f
.
Что касается динамической типизации, существует множество оптимизаций, которые могут быть выполнены, если вы знаете, с какими типами данных вы имеете дело. Например, в Java или C, если у вас есть прямой массив целых чисел, которые вы хотите суммировать, окончательный код сборки может быть таким же простым, как выборка значения в индексе i
, добавление его к accumulator
, а затем увеличение i
.
В Python это очень сложно сделать код оптимальным. Скажем, у вас есть объект подкласса списка, содержащий int
s. Прежде чем добавить любой, Python должен вызвать list.__getitem__(i)
, а затем добавить его в «аккумулятор», вызвав accumulator.__add__(n)
, а затем повторите. Тонны альтернативных поисков могут произойти здесь, потому что другой поток, возможно, изменил, например, метод __getitem__
, dict экземпляра списка или dict класса, между вызовами add или getitem. Даже поиск аккумулятора и списка (и любой переменной, которую вы используете) в локальном пространстве имен вызывает поиск в dict. Эти же накладные расходы применяются при использовании любого пользовательского объекта, хотя для некоторых встроенных типов он несколько смягчается.
Также стоит отметить, что примитивные типы, такие как bigint (int в Python 3, long in Python 2.x), список, набор, dict и т. Д. - это то, что люди много используют в Python. На этих объектах есть тонны встроенных операций, которые уже достаточно оптимизированы. Например, для примера выше вы просто вызываете sum(list)
вместо использования аккумулятора и индекса. Приклеиваясь к ним и немного сокращаясь с помощью функции int / float / complex, вы, как правило, не будете иметь проблемы с производительностью, и если вы это сделаете, возможно, есть небольшая временная критическая единица (например, функция дайджест SHA2), которую вы можете просто перейдите в C (или Java-код, в Jython). Дело в том, что при кодировании C или C ++ вы будете тратить много времени на то, что вы можете сделать за несколько секунд / строк кода Python. Я бы сказал, что компромисс всегда стоит того, за исключением случаев, когда вы делаете что-то вроде встроенного или программирования в реальном времени и не можете себе это позволить.
Нет, вам придется написать свой собственный мост