Что такое руру python
A fast, compliant alternative implementation of Python
On average, PyPy is 4.8 times faster than CPython 3.7
PyPy (with JIT) benchmark times normalized to CPython. Smaller is better. Based on the geometric average of all benchmarks
Advantages and distinct Features
Speed: thanks to its Just-in-Time compiler, Python programs often run faster on PyPy. (What is a JIT compiler?)
Memory usage: memory-hungry Python programs (several hundreds of MBs or more) might end up taking less space than they do in CPython.
Compatibility: PyPy is highly compatible with existing python code. It supports cffi, cppyy, and can run popular python libraries like twisted, and django. It can also run NumPy, Scikit-learn and more via a c-extension compatibility layer.
Stackless: PyPy comes by default with support for stackless mode, providing micro-threads for massive concurrency.
Разновидности модели выполнения
19 июля 2011 г.
Archy
Просмотров: 19143
RSS
Обсудить
Python и запуск програм
CPython, IronPython, Альтернативные реализации Python, Динамический компилятор Psyco
Прежде чем двинуться дальше, я должен заметить, что внутренний поток
выполнения, описанный в предыдущем разделе, отражает современную
стандартную реализацию интерпретатора Python, которая в действительности не
является обязательным требованием самого языка Python. Вследствие этого
модель выполнения склонна изменяться с течением времени. Фактически уже
существуют системы, которые несколько меняют картину, представленную на
рис. Давайте потратим несколько минут, чтобы ознакомиться с наиболее
Альтернативные реализации Python
альтернативные реализации языка Python — CPython, Jython и IronPython, а также
несколько второстепенных реализаций, таких как Stackless Python. В двух
словах: CPython — это стандартная реализация, а все остальные создавались для
специфических целей и задач. Все они реализуют один и тот же язык Python,
но выполняют программы немного по-разному.
CPython
CPython, особенно когда необходимо подчеркнуть ее отличие от двух других
альтернатив. Это название происходит из того факта, что реализация написана
на переносимом языке ANSI С. Это тот самый Python, который вы загружаете
с сайта http://www.python.org, получаете в составе дистрибутива ActivePython
и который присутствует в большинстве систем Linux и Mac OS X. Если вы
обнаружили у себя предварительно установленную версию Python, то более чем
вероятно это будет CPython, — при условии, что ваша компания не использует
какую-то специфическую версию.
Если вы не предполагаете создавать приложения на Java или для платформы
.NET, возможно, вам следует отдать предпочтение стандартной реализации
CPython. Поскольку это эталонная реализация языка, она, как правило,
работает быстрее, устойчивее и лучше, чем альтернативные системы. Рисунок 2.2
отражает модель выполнения CPython.
Jython
альтернативная реализация языка Python, основная цель которой — тесная интеграция
с языком программирования Java. Реализация Jython состоит из Java-классов,
которые выполняют компиляцию программного кода на языке Python в байт-
код Java и затем передают полученный байт-код виртуальной машине Java
(Java Virtual Machine, JVM). Программист помещает инструкции на языке
Python в текстовые файлы как обычно, а система Jython подменяет два
расположенных на рис. 2.2 справа этапа на эквиваленты языка Java.
Цель Jython состоит в том, чтобы позволить программам на языке Python
управлять Java-приложениями, точно так же как CPython может управлять
компонентами на языках С и C++. Эта реализация имеет бесшовную
интеграцию с Java. Поскольку программный код на языке Python транслируется
в байт-код Java, во время выполнения он ведет себя точно так же, как
настоящая программа на языке Java. Сценарии на языке Jython могут выступать
в качестве апплетов и сервлетов, создавать графический интерфейс с
использованием механизмов Java и так далее. Более того, Jython обеспечивает
поддержку возможности импортировать и использовать Java-классы в программном
коде Python. Тем не менее поскольку реализация Jython обеспечивает более
низкую скорость выполнения и менее устойчива по сравнению с CPython, она
представляет интерес скорее для разработчиков программ на языке Java,
которым необходим язык сценариев в качестве интерфейса к Java-коду.
IronPython
языка Python — это IronPython. Она предназначена для обеспечения интеграции
программ Python с приложениями, созданными для работы в среде Microsoft
.NET Framework операционной системы Windows, а также в Mono — открытом
эквиваленте для операционной системы Linux. Платформа .NET и среда
выполнения языка С# предназначены для обеспечения взаимодействий между
программными объектами — независимо от используемого языка
программирования, в духе более ранней модели СОМ компании Microsoft. Реализация
IronPython позволяет программам на языке Python играть роль как
клиентских, так и серверных компонентов, доступных из других языков
Модель реализации IronPython очень напоминает Jython (и фактически
разрабатывается одним и тем же автором) — она подменяет два этапа на рис. 2.2
справа на эквиваленты среды .NET. Кроме того, как и Jython, основной интерес
IronPython представляет для разработчиков, которым необходима
интеграция Python с компонентами .NET. Поскольку разработка ведется компанией
Microsoft, от IronPython, кроме всего прочего, можно было бы ожидать
существенной оптимизации производительности. К моменту написания этих строк
реализация IronPython еще продолжала разрабатываться. За дополнительной
информацией обращайтесь к ресурсам Python или попробуйте самостоятельно
поискать в Сети.1
Средства оптимизации скорости выполнения
похожими способами: исходный программный код компилируют в байт-код
и выполняют полученный байт-код с помощью соответствующей виртуальной
машины. Но кроме них существуют и другие реализации, включая
динамический компилятор Psyco и транслятор Shedskin C++, которые пытаются
оптимизировать основную модель выполнения. Знание этих реализаций не
является для вас обязательным на этой стадии изучения языка Python, тем не менее,
краткий обзор их реализации модели выполнения поможет пролить свет на
модель выполнения в целом.
Динамический компилятор Psyco
Система Psyco — это не другая реализация языка Python, а компонент,
расширяющий модель выполнения байт-кода, что позволяет программам
выполняться быстрее. В терминах схемы на рис. 2.2 Psyco — это расширение PVM,
которое собирает и использует информацию о типах, чтобы транслировать
части байт-кода программы в истинный двоичный машинный код, который
выполняется гораздо быстрее. Для такой трансляции не требуется вносить
изменения в исходный программный код или производить дополнительную
компиляцию в ходе разработки.
Грубо говоря, во время выполнения программы Psyco собирает информацию
о типах объектов и затем эта информация используется для генерации
высокоэффективного машинного кода, оптимизированного для объектов этого
типа. После этого произведенный машинный код замещает соответствующие
участки байт-кода и тем самым увеличивает скорость выполнения программы.
В результате при использовании Psyco существенно уменьшается общее время
выполнения программы. В идеале некоторые участки программного кода под
управлением Psyco могут выполняться так же быстро, как скомпилированный
Поскольку эта компиляция из байт-кода производится во время
выполнения программы, обычно Psyco называют динамическим (just-in-time, JIT)
компилятором. Однако в действительности Psyco немного отличается от JIT-
компиляторов, которые, возможно, некоторые читатели видели в языке Java.
В действительности Psyco — это специализированный ЛТ-компилятор; он
генерирует машинный код, оптимизированный для типов данных, которые
фактически используются в программе. Например, если один и тот же участок
программы использует различные типы данных в разное время, Psyco может
генерировать различные версии машинного кода для поддержки каждой из
Применение Psyco показывает существенное увеличение скорости
выполнения программного кода Python. Согласно информации, которая приводится
на домашней странице проекта, Psyco обеспечивает увеличение скорости «от
2 до 100 раз, обычно в 4 раза, при использовании немодифицированного
интерпретатора Python, неизменного исходного текста, всего лишь за счет
использования динамически загружаемого модуля расширения на языке С».
При прочих равных условиях наибольший прирост скорости наблюдается для
программного кода, реализующего различные алгоритмы на чистом языке
Python, — именно такой программный код обычно переносят на язык С с
целью оптимизации. При использовании Psyco необходимость в таком переносе
теряет свою остроту.
До сих пор Psyco не является стандартной частью Python — его нужно
загружать и устанавливать отдельно. Кроме того, он до сих пор находится на
экспериментальной стадии развития, поэтому вам нужно будет следить за его
разработкой. В действительности, когда я пишу эти строки, Psyco все еще можно
загрузить и установить, но похоже, что большая его часть будет поглощена
более новым проектом «РуРу», который представляет собой попытку переписать
PVM на языке Python с целью обеспечения высокой степени оптимизации, как
Пожалуй, самым большим недостатком Psyco является то обстоятельство, что
в настоящее время он способен генерировать машинный код только для
архитектуры Intel x86, впрочем, на этой архитектуре работают такие операционные
системы, как Windows, Linux и даже Мае. За дополнительной информацией
о расширении Psyco и других попытках реализации JIT-компилятора
обращайтесь на сайт http://www.python.org. Кроме того, вы можете посетить
домашнюю страницу проекта Psyco, которая в настоящее время размещается по
Транслятор Shedskin C++
к выполнению программ на языке Python. Она преобразует исходный код на
языке Python в исходный код на языке C++, который затем может быть
скомпилирован в машинный код. Кроме того, эта система реализует платформоне-
зависимый подход к выполнению программного кода Python. К моменту
написания этих строк система Shedskin еще находилась на экспериментальной
стадии развития и ограничивала программы Python неявным использованием
статических типов, что является ненормальным явлением для программ на
языке Python, поэтому мы не будем углубляться в описание этой системы. Тем
не менее, по предварительным результатам, у нее имеется немалый потенциал,
чтобы выиграть гонку за скоростью как у стандартной реализации Python, так
и у расширения Psyco, и это весьма многообещающий проект. Сведения о
текущем состоянии проекта вы можете самостоятельно найти в Сети.
Фиксированные двоичные файлы
Python, в действительности они просто ищут способ создавать из своих
программ на языке Python самостоятельные исполняемые файлы. Это
необходимо скорее для упаковки и распространения программ, чем для их исполнения,
но эти две стороны взаимосвязаны между собой. При помощи инструментов
сторонних разработчиков, которые можно загрузить из Сети, вы можете
превратить свои программы на языке Python в настоящие исполняемые файлы,
которые в мире Python известны как фиксированные двоичные файлы (frozen
Фиксированные двоичные файлы объединяют в единый файл пакета байт-код
программ, PVM (интерпретатор) и файлы поддержки, необходимые
программам. Существуют разные реализации такого подхода, но в конечном
результате получается единственный исполняемый файл (например, файл с
расширением .ехе в Windows), который легко можно передать заказчику. Такую модель
можно представить, если на рис. 2.2 объединить байт-код и PVM в единый
компонент — фиксированный двоичный файл.
На сегодняшний день существует три основных инструмента создания
фиксированных двоичных файлов: ру2ехе (для Windows), Pylnstaller (напоминает
ру2ехе, но также работает в Linux и UNIX и способен производить
самоустанавливающиеся исполняемые файлы) и freeze (оригинальная версия). Вам
придется загружать эти инструменты отдельно от Python, но они
распространяются совершенно бесплатно. Кроме того, они постоянно развиваются, поэтому
свежую информацию об этих инструментах смотрите на сайте проекта Python
(http://www.python.org) или ищите с помощью поисковых систем. Чтобы дать
вам общее представление об области применения этих инструментов, замечу,
что ру2ехе может создавать автономные программы, использующие
библиотеки tkinter, PMW, wxPython и PyGTK для создания графического интерфейса;
программы, использующие инструментальные средства создания игр pygame;
клиентские программы win32com и многие другие.
Фиксированные двоичные файлы — это не то же самое, что получается в
результате работы настоящего компилятора, потому что они выполняют байт-
код с помощью виртуальной машины. Следовательно, программы в
фиксированных двоичных файлах исполняются с той же скоростью, что и обычные
файлы с исходными текстами программ, разве что улучшен способ их запуска.
Фиксированные двоичные файлы имеют немалый размер (они содержат в себе
PVM), но по современным меркам их все же нельзя назвать необычно
большими. Так как интерпретатор Python встроен непосредственно в фиксированные
двоичные файлы, его установка не является обязательным требованием для
запуска программ на принимающей стороне. Более того, поскольку программный код упакован в фиксированный двоичный файл, он надежно скрыт от
Такая схема упаковки программ в единственный файл особенно подходит для
нужд разработчиков коммерческого программного обеспечения. Например,
программа с графическим интерфейсом на базе tkinter может быть упакована
в исполняемый файл и распространяться как самостоятельная программа на
CD или через Интернет. Конечному пользователю не нужно будет
устанавливать Python (и даже знать о том, что это такое), чтобы запустить
Другие способы выполнения
преследующие узкоспециализированные цели:
• Система Stackless Python — это разновидность стандартной реализации
CPython, которая не использует стек вызовов языка С. Она упрощает
перенос Python на архитектуры с небольшим объемом стека, обеспечивает
дополнительные возможности параллельной обработки данных и поощряет
использование новейших инструментов языка, таких как сопрограммы.
• Система Cython (расширенная версия проекта Ругех) — это гибридный
язык, дополняющий язык Python возможностью вызывать функции на
языке С и использовать объявления типов переменных, аргументов и
атрибутов классов на языке С. Исходные тексты на языке Cython могут быть
скомпилированы в программный код на языке С, использующий Python/C
API, который в свою очередь может быть скомпилирован в машинный код.
Несмотря на то, что получающийся программный код не полностью
совместим со стандартным языком Python, Cython может оказаться как
полезным инструментом для создания оберток вокруг внешних библиотек на
языке С, так и эффективным средством разработки расширений на С для
Дополнительные подробности об этих системах вы без труда найдете в
Будущие возможности
здесь, в действительности является лишь отражением текущей реализации
интерпретатора Python, но не самого языка программирования. Например,
вполне возможно, что в течение времени, пока эта книга будет сохранять
актуальность (едва ли она сохранится у кого-нибудь через десять лет), появится
традиционный компилятор для трансляции исходного текста на языке Python
в машинный код. Кроме того, в будущем могут появиться новые варианты
реализации интерпретатора и разновидности байт-кода. Например:
• Проект Parrot поставил перед собой цель выработать единый формат байт-
кода, единую виртуальную машину и методики оптимизации для
различных языков программирования (подробности на сайте http://’www.python,
org). Стандартная виртуальная машина PVM в интерпретаторе пока
выполняет программный код быстрее, чем Parrot, но пока неясно, как будет
развиваться этот проект.
• Проект РуРу — попытка реализовать PVM непосредственно на языке
Python, что позволит использовать новые приемы программирования. Его
цель- создать быструю и гибкую реализацию Python.
• Проект Unladen Swallow, поддерживаемый компанией Google, поставил
перед собой задачу повысить производительность стандартного
интерпретатора Python по меньшей мере в 5 раз, что позволит использовать его в качестве
замены языку С во многих проектах. Предполагается, что в результате этой
оптимизации будет создана полностью совместимая версия CPython,
которая выполняется гораздо быстрее. Участники этого проекта также
надеются удалить глобальную блокировку Python (Global Interpreter Lock, GIL),
которая препятствует возможности одновременного выполнения
нескольких потоков управления. В настоящее время этот проект разрабатывается
инженерами из Google как проект с открытыми исходными текстами —
изначально за основу в нем была принята версия Python 2.6, однако вполне
возможно, что изменения смогут быть внесены и в версию 3.0.
Дополнительные подробности вы найдете на сайте компании Google.
Подобные грядущие схемы реализации могут несколько изменить схему
времени выполнения интерпретатора Python, однако, скорее всего компилятор
байт-кода останется стандартом еще какое-то время. Переносимость и
гибкость байт-кода во время выполнения — это очень важные качества многих
реализаций Python. Более того, добавление в язык конструкций объявления
типов с целью обеспечения статической компиляции только повредит гибкости,
осмысленности, простоте и общему духу языка Python. Из-за динамической
природы языка Python любые реализации в будущем, скорее всего, сохранят
некоторые черты нынешней PVM.
«Learning Python, Fourth Edition, by
Mark Lutz. Copyright 2009 O’Reilly Media, Inc., 978-0-596-15806-4».
Оптимизация Python: простые способы ускорить и очистить код
Сам по себе язык программирования Python очень хорош и используется во многих сферах IT. Но у него есть один существенный минус, который тянется за ним шлейфом — это низкая производительность по сравнению с другими языками. Поэтому для программ на Python очень необходима оптимизация.
Нет смысла сейчас обсуждать чем вызвана медлительность Python, потому что на эти качества пока невозможно повлиять, так как они являются особенностью этого языка. При этом можно применить ряд инструментов и подходов при написании кода на Python, чтобы ускорить работу программ на этом языке силами самого языка.
Оптимизация Python
-
Использовать специальные модули для ускорения работы программ на Питоне по типу Psyco. Но такие модули имеют слабую поддержку и непонятно сколько они еще прослужат, хотя ускоряют работу Python-программ на десятки процентов.
-
Использовать Python C Extensions, чтобы переписать часть кода программы на языке С, тем самым ускорив ее производительность. Но для этого нужно обладать дополнительными знаниями, например знать тот же язык «С» и технологию C API. Помимо этого очень сильно снижается скорость разработки программ «Python+С».
-
Сменить используемые алгоритмы. Но и тут иногда возникает такая ситуация, что используется достаточно «шустрый» алгоритм и заменить не на что, но при этом скорость работы программы не радует.
Оптимизация производительности Python его же инструментами
Приведем несколько рекомендаций, как проводится оптимизация Python, а конкретнее, на что нужно обращать внимание в процессе разработки, чтобы конечный скрипт работал эффективнее.
Избегать применения глобальных переменных
Чрезмерное применение глобальных переменных в любых языках программирования считается дурным тоном. Потому что такое действие может п о влечь за собой множество побочных эффектов, от которых тяжело будет избавит ь ся. Множественное применение глобальных переменных очень часто приводит к спагетти-коду, что вызывает дополнительные трудности и проблемы.
Специфика Python такова, что он очень медленно обрабатывает доступ к глобальным переменным, особенно внутри циклов. Поэтому их меньшее количество — это первый шаг ускорить работу Питона.
Внешние библиотеки
-
«cPickle», а не «pickle»;
-
<Cython> — это библиотека для Питона, которая поддерживает функции и типы С;
-
РуРу — это JIT-компилятор, который ускоряет код Python;
-
пакет Pandarallel, который распараллеливает операции на несколько процессов;
-
библиотеку NumPy;
-
и многое другое.
Применение встроенных инструментов Python
-
функцию map();
-
модуль cProfile;
-
«list Component», где это возможно, вместо «For Loop»;
-
связанные списки;
-
функции range() и xrange();
-
наборы Python;
-
метод join();
-
и др.
Работа над кодом
-
применять внутренние инструменты Python ;
-
не создавать лишние глобальные переменные, тщательно подбирать библиотеки и расширения;
-
по возможности внедрять код С;
-
писать сам код обдуманно и максимально лаконично;
-
по возможности внедрять кеширование объектов;
-
не создавать лишние экземпляры объектов;
-
и др.
Заключение
В программировании бытует мнение, что любой написанный код, в первую очередь, должен быть эффективным и рабочим. Только потом можно приступать к его оптимизации. При этом в Python оптимизация должна проходит прямо в процессе разработки, так как она состоит из множества мелких моментов, которые потом будет сложно изменить.
Оптимизация производительности Python не имеет четкого алгоритма действий. Над этой проблемой многие разработчики «бьются» по-своему, поэтому мест, где можно оптимизировать код Питона , очень много. Иногда даже незначительные изменения типа «вместо «**» правильно написать «*» в нужном месте» могут ускорить работу кода Python в несколько раз. Оптимизация Python — это придание важности даже мелочам, поэтому экспериментируйте.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Почему существует так много Питонов?
Удивительно, но это довольно неоднозначное заявление. Что я имею ввиду под “Питоном”? Может, абстрактный интерфейс Питона? Или CPython, распространенная реализация Питона (не путать с похожим по названию Cython)? Или я имею ввиду что-то совсем иное? Может, я косвенно ссылаюсь на Jython, или IronPython, или PyPy. Или может я отвлекся так сильно, что говорю о RPython или RubyPython (которые очень сильно отличаются).
Не смотря на схожесть в названиях указанных выше технологий, некоторые из них имеют совсем другие задачи (или, как минимум, работают совершенно иными способами)
При работе с Питоном я столкнулся с кучей таких технологий. Инструменты *ython. Но лишь недавно я уделил время, чтобы разобраться, что они собой представляют, как они работают и почему они (каждая по-своему) необходимы.
В этом посте я начну с нуля и пройдусь по разным реализациям Питона, а закончу подробным введением в PyPy, за которым, по моему мнению, будущее языка.
Все начинается с понимания того, чем на самом деле является “Питон”.
Если у вас хорошее понимание машинного кода, виртуальных машин и так далее, можете пропустить этот раздел.
Питон интерпретируемый или компилируемый?
Это распространенный источник непонимания среди новичков Питона.
Первое, что необходимо понять: “Питон” – это интерфейс. Существует спецификация, описывающая, что должен делать Питон, и как он должен себя вести (что справедливо для любого интерфейса). И существует несколько имплементаций (что также справедливо для любого интерфейса).
Второе: “интерпретируемый” и “компилируемый” это свойства имплементации, но не интерфейса.
Так что сам вопрос не совсем корректен.
В случае с самой распространенной реализацией (CPython: написанный на C, часто называемый просто “Python”, и, конечно, именно тот, который вы используете, если понятия не имеете о чем я толкую) ответ: интерпретируемый, с некоторой компиляцией. CPython компилирует* исходный код на Питоне в байткод, а затем интерпретирует этот байткод, запуская его в процессе.
* Замечание: это не совсем “компиляция” в традиционном смысле. Обычно, мы считаем, что “компиляция” это конвертация из высокоуровневого языка в машинный код. Тем не менее – в некотором роде это “компиляция”.
Давайте изучим этот ответ получше, так как он поможет нам понять некоторые концепции, ожидающие нас в этой статье.
Байткод или машинный код
Очень важно понять разницу между байткодом и машинным (или нативным) кодом. Пожалуй, легче всего ее понять на примере:
— Cи компилируется в машинный код, который впоследствии запускается напрямую процессором. Каждая инструкция заставляет процессор производить разные действия.
— Java компилируется в байткод, который впоследствии запускается на Виртуальной машине Java (Java Virtual Machine, JVM), абстрактном компьютере, который запускает программы. Каждая инструкция обрабатывается JVM, который взаимодействует с компьютером.
Сильно упрощая: машинный код намного быстрее, но байткод лучше переносим и защищен.
Машинный код может отличаться в зависимости от машины, тогда как байткод одинаковый на всех машинах. Можно сказать, что машинный код оптимизирован под вашу конфигурацию.
Возвращаясь к CPython, цепочка операций выглядит следующим образом:
1. CPython компилирует ваш исходный код на Питоне в байткод.
2. Этот байткод запускается на виртуальной машине CPython.
Альтернативные виртуальные машины: Jython, IronPython и другие
Как я говорил выше, у Питона существует несколько реализаций. Опять же, как говори-лось выше, самой популярной является CPython. Эта версия Питона написана на C и считается имплементацией “по умолчанию”.
Но как насчет альтернатив? Одна из наиболее видных это Jython, реализация Питона на Java, которая использует JVM. В то время как CPython генерирует байткод для запуска на CPython VM, Jython генерирует байткод Java для запуска на JVM (это то же самое, что генерируется при компиляции программы на Java).
“Зачем может понадобиться использовать альтернативную реализацию?”, спросите вы. Ну, для начала, разные реализации хорошо ладят с разными наборами технологий.
CPython упрощает написание C-расширений для кода на Питоне потому что в конце он запускается интерпретатором Cи. Jython в свою очередь упрощает работу с другими программами на Java: вы можете импортировать любые Java-классы без дополнительных усилий, призывая и используя ваши Java-классы из программ на Jython. (Замечание: если вы еще не думали об этом всерьез, это довольно безумно. Мы дожили до того времени, когда можно смешивать разные языки и компилировать их в одну сущность. Как заметил Rostin, программы, смешивающие код на Фортране с Cи появились довольно давно, так что это не совсем новинка. Но это все же круто.)
В качестве примера, вот корректный код на Jython:
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_51
>>> from java.util import HashSet
>>> s = HashSet(5)
>>> s.add(«Foo»)
>>> s.add(«Bar»)
>>> s
[Foo, Bar]
IronPython это другая популярная реализация Питона, написанная полностью на C# и предназначенная для .NET. В частности, она запускается на виртуальной машине .NET, если ее можно так назвать, на Common Language Runtime (CLR), от Майкрософт, сравнимым с JVM.
Можно сказать, что Jython: Java :: IronPython: C#. Они работают на соответствующих виртуальных машинах, есть возможность импортировать классы C# в код IronPython и классы Java в код Jython, и так далее.
Вполне реально выжить, не прикасаясь к ни к чему, кроме CPython. Но, переходя на другие имплементации, вы получаете преимущество, в основном из-за используемого стека технологий. Используете много языков, основанных на JVM? Jython может вам подойти. Все на .NET? Возможно, стоит попробовать IronPython (и, возможно, вы уже сделали).
Кстати, хоть это и не станет причиной для перехода на другую имплементацию, стоит упомянуть, что имплементации эти на самом деле отличаются поведением. Это касается не только способов интерпретации кода на Питоне. Однако эти отличия, как правило, не-значительны, они исчезают и появляются со временем из-за активной разработки. К примеру, IronPython использует строки Unicode по умолчанию; однако CPython использует ASCII в версиях 2.x (выдавая ошибку UnicodeEncodeError для не-ASCII символов), и при этом поддерживает символы Unicode по умолчанию в версиях 3.x.
Компиляция на лету (Just-in-Time Compilation): PyPy и будущее
Итак, у нас есть имплементация Питона, написанная на Си, еще одна – на Java, и третья на C#. Следующий логичный шаг: имплементация Питона, написанная на… Питоне. (Подготовленный читатель заметит, что это утверждение немного обманчиво).
Вот почему это может сбивать с толку. Для начала, давайте обсудим компиляцию на лету (just-in-time или JIT).
JIT. Почему и как
Напомню, что нативный машинный код намного быстрее байткода. Ну, а что, если бы можно было компилировать часть байткода и запускать его как нативный код? Пришлось бы “заплатить” некоторую цену (иными словами: время) за компиляцию байткода, но если результат будет работать быстрее, то это здорово! Этим и мотивируется JIT-компиляция, гибридная техника, которая совмещает в себе преимущества интерпретато-ров и компиляторов. В двух словах – JIT старается использовать компиляцию, чтобы ускорить систему интерпретации.
Например, вот распространенный подход JIT:
- Определить байткод, который запускается часто.
- Скомпилировать его в нативный машинный код.
- Закэшировать результат.
- Всегда когда необходимо запустить тот же самый байткод, использовать уже скомпилированный машинный код и пожинать плоды (в частности, прирост скорости).
В этом вся суть PyPy: использовать JIT в Питоне (в дополнении можно найти предыдущие попытки). Конечно, есть и другие цели: PyPy нацелен на кроссплатформенность, работу с небольшим количеством памяти и поддержку stackless (отказа от стека вызовов языка Си в пользу собственного стека). Но JIT это главное преимущество. В среднем на основе временных тестов, фактор ускорения составляет 6.27. Более подробные данные можно получить из схемы от PyPy Speed Center:
В PyPy сложно разобраться
У PyPy есть огромный потенциал, и в данный момент он хорошо совместим с CPython (так что на нем можно запускать Flask, Django, и т.д.).
Но с PyPy есть много путаницы. (оцените, к примеру, это бессмысленное предложение создать PyPyPy…). По моему мнению основная причина в том, что PyPy одновременно является:
1. Интерпретатором Питона, написанным на RPython (не Python (я обманул вас до этого)). RPython это подмножество Python со статичной типизацией. В Python, вести тщательные беседы о типах “в целом невозможно” почему это так сложно? рассмотрите следующее:
x = random.choice([1, «foo»])
это корректный код на Python (спасибо Ademan‘у). Какой тип у x? Как мы можем обсуждать типы переменных, когда типы даже не форсируются?). В RPython мы жертвуем некоторой гибкостью, но взамен получаем возможность гораздо проще управлять памятью и много чего еще, что помогает при оптимизации.
2. Компилятором, который компилирует код на RPython в разные форматы и поддерживает JIT. Платформой по-умолчанию является Си, то есть компилятор RPython-в-Си, но в качестве целевой платформы также можно выбрать JVM и другие.
Для простоты описания, я буду называть их PyPy (1) и PyPy (2).
Зачем могут понадобиться эти две вещи, и почему – в одном наборе? Думайте об этом так: PyPy (1) это интерпретатор, написанный на RPython. То есть он берет пользовательский код на Питоне и компилирует его в байткод. Но чтобы сам интерпретатор (написанный на RPython) мог работать, он должен быть интерпретирован другой реализацией Пи-тона, верно?
Итак, можно просто использовать CPython чтобы запускать интерпретатор. Но это будет не слишком быстро.
Вместо этого мы используем PyPy (2) (называемый RPython Toolchain) чтобы компилировать интерпретатор PyPy в код для другой платформы (например, C, JVM, или CLI) для запуска на конечной машине, с добавлением JIT. Это волшебно: PyPy динамически добавляет JIT к интерпретатору, генерируя собственный компилятор! (Опять же, это безумие: мы компилируем интерпретатор, добавляя другой отдельный, самостоятельный компилятор).
В конце концов результатом будет самостоятельный исполняемый файл, который интерпретирует исходный код на Питоне и использует оптимизацию JIT. То, что нужно! Понять сложновато, но, возможно, эта схема поможет:
Повторим: настоящая красота PyPy в том, что мы можем написать себе кучу разных интерпретаторов Питона на RPython не волнуясь о JIT (не считая пары деталей). После этого PyPy реализует для нас JIT, используя RPython Toolchain/PyPy (2).
На самом деле, если копнуть глубже в абстракцию, теоретически можно написать интерпретатор любого языка, направить его в PyPy и получить JIT для этого языка. Это возможно потому, что PyPy концентрируется на оптимизации самого интерпретатора, а не деталей языка, который тот интерпретирует.
В качестве отступления я бы хотел заметить, что сам JIT совершенно восхитителен. Он использует технику под названием “отслеживание” (tracing), которая работает следующим образом:
- Запустить интерпретатор и интерпретировать все (не добавляя JIT).
- Провести легкое профилирование интерпретированного кода.
- Определить операции, которые уже выполнялись ранее.
- Скомпилировать эти части кода в машинный код.
Узнать больше можно из этой легкодоступной и очень интересной публикации.
Подытожим: мы используем PyPy-компилятор RPython-в-Си (или другую целевую плат-форму), чтобы скомпилировать реализованный на RPython интерпретататор PyPу.
Заключение
Почему все это так восхитительно? Почему стоит гнаться за этой безумной идеей? По-моему, Алекс Гейнор объяснил это очень хорошо в своем блоге: “[За PyPy будущее] потому что [он] более быстрый, более гибкий и является лучшей платформой для развития Питона”.
- Он быстрый – потому что компилирует исходный код в нативный код (используя JIT).
- Он гибкий – потому что добавляет JIT в интерпретатор без особых усилий.
- Он гибкий (опять) – потому что вы можете писать интерпретаторы в RPython, что впоследствии упрощает расширение по сравнению с тем же Си (на самом деле упрощает настолько, что даже есть инструкция по написанию собственных интерпретаторов).
Дополнение: другие названия, которые вы, возможно, слышали
Python 3000 (Py3k): альтернативное название Python 3.0, основной релиз Питона с обратной совместимостью, который появился в 2008. году. Команда Py3k предсказала, что новой версии понадобится примерно пять лет чтобы полностью прижиться. И в то время, как большинство (внимание: надуманное утверждение) разработчиков на Питоне продолжают использовать Python 2.x, люди все больше задумываются о Py3k.
- Задача: позволить писать расширения Си для программ на Питоне.
- Также позволяет добавлять статическую типизацию в существующий код на Питоне, что после повторной компиляции может помочь достичь похожей на Си производительности.
- Напоминает PyPy, но это не то же самое. В случае с Cython вы форсируете типизацию в пользовательском коде перед подачей компилятору. В PyPy вы пишете старый добрый Python, а компилятор отвечает за любую оптимизацию.
Numba: “специализированный just-in-time компилятор”, который добавляет JIT в снабженный примечаниями код на Питоне. Проще говоря, вы даете ему подсказки, а он ускоряет некоторые части вашего кода. Numba является частью дистрибутива Anaconda набора пакетов для анализа и управления данными.
IPython: сильно отличается от всего, что мы обсудили. Вычислительная среда для Питона. Интерактивная, с поддержкой GUI-пакетов, браузеров и так далее.
Psyco: модуль расширения Питона, одна из первых попыток Питона в области JIT. Давно помечен как “неподдерживаемый и мертвый”. Главный разработчик Psyco Армин Риго сейчас работает над PyPy.