Какво е PyPy? По-бърз Python без болка

Python си спечели репутацията на мощен, гъвкав и лесен за работа. Тези добродетели доведоха до използването му в огромно и нарастващо разнообразие от приложения, работни потоци и полета. Но дизайнът на езика - неговата интерпретирана същност, динамичността му по време на изпълнение - означава, че Python винаги е бил с порядък по-бавен от машинните езици като C или C ++.

През годините разработчиците са измислили различни решения за ограниченията на скоростта на Python. Например, можете да напишете задачи с висока производителност в C и да го увиете с Python; много библиотеки за машинно обучение правят точно това. Или можете да използвате Cython, проект, който ви позволява да поръсите Python кода с информация за типа на изпълнението, която позволява да се компилира в C.

Но заобикалящите решения никога не са идеални. Не би ли било чудесно, ако можем просто да вземем съществуваща програма на Python  такава , каквато е , и да я стартираме драстично по-бързо? Точно това ви позволява да направите PyPy.

Свързано видео: Използване на PyPy време за изпълнение за Python

PyPy срещу CPython

PyPy е заместващ заместител на основния интерпретатор на Python, CPython. Докато CPython компилира Python в междинен байт код, който след това се интерпретира от виртуална машина, PyPy използва компилация точно навреме (JIT), за да преведе Python кода в машинен език за монтаж.

В зависимост от изпълняваната задача, подобренията в производителността могат да бъдат драматични. Средно PyPy ускорява Python с около 7,6 пъти, като някои задачи се ускоряват 50 пъти или повече. Интерпретаторът CPython просто не извършва същите видове оптимизации като PyPy и вероятно никога няма да го направи, тъй като това не е една от целите му за проектиране.

Най-хубавото е, че от разработчика не са необходими малко или никакви усилия за отключване на печалбите, които PyPy предоставя. Просто разменете CPython за PyPy и в по-голямата си част сте готови. Има няколко изключения, обсъдени по-долу, но заявената цел на PyPy е да стартира съществуващ, немодифициран код на Python и да му осигури автоматично увеличаване на скоростта.

Понастоящем PyPy поддържа както Python 2, така и Python 3, чрез различни превъплъщения на проекта. С други думи, трябва да изтеглите различни версии на PyPy в зависимост от версията на Python, която ще използвате. Клонът на Python 2 на PyPy съществува много по-дълго, но версията на Python 3 е ускорена в последно време. Понастоящем поддържа както Python 3.5 (производствено качество), така и Python 3.6 (бета качество).

В допълнение към поддържането на целия основен език Python, PyPy работи с по-голямата част от инструментите в екосистемата на Python, като например  pip за опаковане или  virtualenv за виртуална среда. Повечето пакети на Python, дори тези с C модули, трябва да работят както е, въпреки че има ограничения, които ще разгледаме по-долу.

Как работи PyPy

PyPy използва техники за оптимизация, открити в други точно навреме компилатори за динамични езици. Той анализира работещите програми на Python, за да определи информацията за типа на обектите, когато те са създадени и използвани в програмите, след което използва тази информация за тип като ръководство за ускоряване на нещата. Например, ако функция на Python работи само с един или два различни типа обекти, PyPy генерира машинен код за обработка на тези конкретни случаи.

Оптимизациите на PyPy се обработват автоматично по време на изпълнение, така че обикновено не е необходимо да променяте производителността му. Един напреднал потребител може да експериментира с опциите на командния ред на PyPy, за да генерира по-бърз код за специални случаи, но това е рядко необходимо.

PyPy също се отклонява от начина, по който CPython обработва някои вътрешни функции, но се опитва да запази съвместимо поведение. Например PyPy обработва събирането на боклука по различен начин от CPython. Не всички обекти се събират веднага, след като излязат извън обхвата, така че програма на Python, работеща под PyPy, може да покаже по-голям отпечатък от паметта, отколкото когато се изпълнява под CPython. Но все пак можете да използвате контрола за събиране на боклук Питон на високо равнище, изложени през gcмодул, като например gc.enable(), gc.disable()и gc.collect().

Ако искате информация за JP поведението на PyPy по време на изпълнение, PyPy включва модул pypyjit, който излага много JIT куки на вашето приложение на Python. Ако имате функция или модул, който изглежда се представя слабо с JIT, pypyjitви позволява да получите подробна статистика за него.

Друг специфичен за PyPy модул __pypy__излага други функции, специфични за PyPy, така че може да бъде полезен за писане на приложения, които използват тези функции. Поради динамичната динамика на Python е възможно да се конструират приложения на Python, които използват тези функции, когато PyPy присъства и ги игнорира, когато не е.

Ограничения на PyPy

Магически, колкото може да изглежда PyPy, това не е магия. PyPy има определени ограничения, които намаляват или избягват ефективността му за определени видове програми. Уви, PyPy не е напълно универсален заместител на стандартното изпълнение на CPython.

PyPy работи най-добре с чисти приложения на Python

PyPy винаги се е представял най-добре с „чисти“ приложения на Python - т.е. приложения, написани на Python и нищо друго. Пакетите на Python, които взаимодействат с C библиотеки, като NumPy, също не са се справили поради начина, по който PyPy емулира родния двоичен интерфейс на CPython. 

Разработчиците на PyPy се справят с този проблем и правят PyPy по-съвместим с повечето пакети на Python, които зависят от C разширения. Numpy, например, работи много добре с PyPy сега. Но ако искате максимална съвместимост с C разширения, използвайте CPython.

PyPy работи най-добре с по-продължителни програми

Един от страничните ефекти на това как PyPy оптимизира програмите на Python е, че по-продължителните програми се възползват най-много от неговите оптимизации. Колкото по-дълго се изпълнява програмата, толкова повече информация за типа изпълнение може да събере PyPy и толкова повече оптимизации може да направи. Еднократните скриптове на Python няма да се възползват от подобни неща. Приложенията, които се възползват, обикновено имат цикли, които се изпълняват за дълги периоди от време или се изпълняват непрекъснато във фонов режим - например уеб рамки.

PyPy не прави компилация преди време

PyPy  компилира  код на Python, но не  е компилатор  за код на Python. Поради начина, по който PyPy извършва своите оптимизации и присъщата динамика на Python, няма начин да се излъчи полученият JITted код като самостоятелен двоичен файл и да се използва повторно. Всяка програма трябва да бъде съставена за всяко изпълнение. Ако искате да компилирате Python в по-бърз код, който може да работи като самостоятелно приложение, използвайте Cython, Numba или текущия експериментален проект Nuitka.