Što je PyPy? Brži Python bez boli

Python je stekao reputaciju moćnog, fleksibilnog i jednostavnog za rad. Te su vrline dovele do njegove upotrebe u ogromnoj i rastućoj raznolikosti aplikacija, tijekova rada i polja. Ali dizajn jezika - njegova interpretirana priroda, dinamičnost izvođenja - znači da je Python uvijek bio reda veličine sporiji od jezika koji su materinji poput C ili C ++.

Tijekom godina programeri su osmislili razne zaobilazne načine za Pythonova ograničenja brzine. Na primjer, u C biste mogli pisati zadatke koji zahtijevaju velike performanse i omotati ih Pythonom; mnoge knjižnice strojnog učenja rade upravo to. Ili biste mogli upotrijebiti Cython, projekt koji vam omogućuje posipanje Python koda informacijama o vrsti izvođenja koje omogućuju njegovu kompajliranje u C.

Ali zaobilazna rješenja nikad nisu idealna. Ne bi li bilo sjajno kad bismo mogli jednostavno uzeti postojeći Python program  kakav jest i pokrenuti ga dramatično brže? Upravo to vam omogućuje PyPy.

Srodni video: Korištenje PyPy vremena izvođenja za Python

PyPy vs. CPython

PyPy je zamjenska zamjena za standardni Python interpreter, CPython. Dok CPython kompajlira Python u srednji bajt kod koji se zatim interpretira na virtualnom stroju, PyPy koristi JIT-ovu kompilaciju za prevođenje Python koda u strojni materinji jezik sklopa.

Ovisno o zadatku koji se izvodi, dobici u izvedbi mogu biti dramatični. U prosjeku PyPy ubrzava Python oko 7,6 puta, a neki zadaci ubrzavaju i 50 puta ili više. CPython interpreter jednostavno ne izvodi iste vrste optimizacija kao PyPy, a vjerojatno to nikada neće ni učiniti, jer to nije jedan od njegovih ciljeva dizajna.

Najbolje je to što je programeru potrebno malo ili nimalo napora kako bi otključao dobitak koji PyPy pruža. Jednostavno zamijenite CPython za PyPy i većinom ste gotovi. Postoji nekoliko iznimaka, o kojima ćemo raspravljati u nastavku, ali PyPy-ov navedeni cilj je pokretanje postojećeg, neizmijenjenog Python koda i pružanje automatskog pojačanja brzine.

PyPy trenutno podržava i Python 2 i Python 3, putem različitih inkarnacija projekta. Drugim riječima, trebate preuzeti različite verzije PyPy-a, ovisno o verziji Pythona koju ćete pokretati. Python 2 grana PyPy-a postoji mnogo duže, ali verzija Python 3 ubrzo je ubrzana. Trenutno podržava i Python 3.5 (kvaliteta proizvodnje) i Python 3.6 (beta kvaliteta).

Osim što podržava čitav temeljni jezik Python, PyPy radi s velikom većinom alata u ekosustavu Python, poput  pip pakiranja ili  virtualenv virtualnih okruženja. Većina Python paketa, čak i oni s C modulima, trebali bi raditi takvi kakvi jesu, iako postoje ograničenja o kojima ćemo govoriti u nastavku.

Kako PyPy radi

PyPy koristi tehnike optimizacije pronađene u drugim pravovremenim kompajlerima za dinamičke jezike. Analizira pokrenute Python programe kako bi odredio informacije o tipu objekata dok su stvoreni i koriste se u programima, a zatim koristi te podatke o tipu kao vodič za ubrzanje stvari. Na primjer, ako Python funkcija radi sa samo jednim ili dva različita tipa objekta, PyPy generira strojni kôd za obradu tih specifičnih slučajeva.

Optimizacije PyPy-a obrađuju se automatski tijekom izvođenja, tako da uglavnom ne trebate podesiti njegove performanse. Napredni korisnik može eksperimentirati s PyPy-jevim opcijama naredbenog retka kako bi generirao brži kod za posebne slučajeve, ali to je rijetko potrebno.

PyPy također odstupa od načina na koji CPython rukuje nekim unutarnjim funkcijama, ali pokušava sačuvati kompatibilna ponašanja. Na primjer, PyPy s odvoženjem smeća postupa drugačije od CPythona. Ne prikupljaju se svi objekti odmah nakon što izađu iz opsega, pa program Python koji se izvodi pod PyPyom može pokazati veći memorijski otisak nego kad se izvodi pod CPythonom. No, i dalje možete koristiti kontrole odvoz smeća Pythona visokoj razini izloženi putem gcmodula, kao što su gc.enable(), gc.disable()i gc.collect().

Ako želite informacije o PyPyjevom JIT ponašanju u vrijeme izvođenja, PyPy uključuje modul pypyjit, koji izlaže mnoge JIT kuke vašoj Python aplikaciji. Ako imate funkciju ili modul koji izgleda loše s JIT-om, pypyjitomogućuje vam dobivanje detaljne statistike o njemu.

Drugi modul __pypy__specifičan za PyPy, izlaže druge značajke specifične za PyPy, pa može biti koristan za pisanje aplikacija koje koriste te značajke. Zbog Pythonove dinamičnosti izvršavanja, moguće je izraditi Python aplikacije koje koriste ove značajke kada je PyPy prisutan i ignorira ih kad nije.

PyPy ograničenja

Magično koliko se PyPy čini, nije čarolija. PyPy ima određena ograničenja koja smanjuju ili umanjuju njegovu učinkovitost za određene vrste programa. Nažalost, PyPy nije potpuno univerzalna zamjena za stock CPython vrijeme izvođenja.

PyPy najbolje radi s čistim Python aplikacijama

PyPy se uvijek najbolje ponašao s "čistim" Python aplikacijama - tj. Aplikacijama napisanim na Pythonu i ničim drugim. Python paketi koji se povezuju s C bibliotekama, kao što je NumPy, također nisu uspjeli zbog načina na koji PyPy oponaša CPythonova izvorna binarna sučelja. 

Programeri PyPy-a riješili su ovaj problem i učinili PyPy kompatibilnijim s većinom Python paketa koji ovise o C proširenjima. Numpy, na primjer, sada jako dobro surađuje s PyPyjem. Ali ako želite maksimalnu kompatibilnost s C proširenjima, upotrijebite CPython.

PyPy najbolje funkcionira s programima koji rade duže

Jedna od nuspojava načina na koji PyPy optimizira programe Python jest da programi koji rade dulje imaju najviše koristi od njegove optimizacije. Što se program duže izvodi, PyPy može prikupiti više informacija o tipu vremena izvođenja i više optimizacija. Jednostavne Python skripte neće imati koristi od takvih stvari. Aplikacije koje imaju koristi obično imaju petlje koje se izvode dulje vrijeme ili se kontinuirano izvode u pozadini - na primjer, mrežni okviri.

PyPy ne radi kompilaciju unaprijed

PyPy  kompajlira  Python kôd, ali nije  kompajler  za Python kôd. Zbog načina na koji PyPy izvodi svoje optimizacije i svojstvene dinamičnosti Pythona, ne postoji način da se emitira rezultirajući JITted kôd kao samostalni binarni sustav i ponovno ga koristi. Svaki program mora se sastaviti za svako pokretanje. Ako želite kompajlirati Python u brži kôd koji se može pokretati kao samostalna aplikacija, upotrijebite Cython, Numba ili trenutno eksperimentalni Nuitka projekt.