Programmering

Hva er PyPy? Raskere Python uten smerter

Python har fått rykte på seg for å være kraftig, fleksibel og enkel å jobbe med. Disse dyder har ført til bruk i et stort og voksende utvalg av applikasjoner, arbeidsflyter og felt. Men utformingen av språket - dets tolkede natur, kjøretidsdynamikken - betyr at Python alltid har vært en størrelsesorden langsommere enn maskininnfødte språk som C eller C ++.

Gjennom årene har utviklere kommet med en rekke løsninger for Pythons hastighetsbegrensninger. For eksempel kan du skrive ytelsesintensive oppgaver i C og pakke den inn med Python; mange maskinlæringsbiblioteker gjør akkurat dette. Eller du kan bruke Cython, et prosjekt som lar deg strø Python-kode med kjøretidsinformasjon som gjør det mulig å kompilere den til C.

Men løsninger er aldri ideelle. Ville det ikke vært bra hvis vi bare kunne ta et eksisterende Python-programsom det er, og kjøre det dramatisk raskere? Det er akkurat det PyPy lar deg gjøre.

Relatert video: Bruke PyPy-kjøretiden for Python

PyPy vs. CPython

PyPy er en drop-in erstatning for lager Python tolk, CPython. Mens CPython kompilerer Python til mellombytekode som deretter tolkes av en virtuell maskin, bruker PyPy just-in-time (JIT) kompilering for å oversette Python-kode til maskininnfødt monteringsspråk.

Avhengig av oppgaven som utføres, kan ytelsesgevinsten være dramatisk. I gjennomsnitt øker PyPy Python omtrent 7,6 ganger, med noen oppgaver akselerert 50 ganger eller mer. CPython-tolk utfører rett og slett ikke de samme typer optimaliseringer som PyPy, og vil sannsynligvis aldri, siden det ikke er et av designmålene.

Den beste delen er at det kreves liten eller ingen innsats fra utviklerens side for å låse opp gevinsten PyPy gir. Bare bytt ut CPython for PyPy, og for det meste er du ferdig. Det er noen unntak, diskutert nedenfor, men PyPys uttalte mål er å kjøre eksisterende, umodifisert Python-kode og gi den en automatisk hastighetsforbedring.

PyPy støtter for tiden både Python 2 og Python 3, ved hjelp av forskjellige inkarnasjoner av prosjektet. Med andre ord må du laste ned forskjellige versjoner av PyPy, avhengig av hvilken versjon av Python du skal kjøre. Python 2-grenen av PyPy har eksistert mye lenger, men Python 3-versjonen har blitt satt opp i fart så sent. Den støtter for tiden både Python 3.5 (produksjonskvalitet) og Python 3.6 (beta-kvalitet).

I tillegg til å støtte hele kjernen til Python-språket, fungerer PyPy med de aller fleste verktøyene i Python-økosystemet, som f.eks.pip for emballasje ellervirtualenv for virtuelle miljøer. De fleste Python-pakker, selv de med C-moduler, bør fungere som de er, selv om det er begrensninger vi vil gå inn på nedenfor.

Hvordan PyPy fungerer

PyPy bruker optimaliseringsteknikker som finnes i andre just-in-time kompilatorer for dynamiske språk. Den analyserer kjørende Python-programmer for å bestemme typeinformasjonen til objekter mens de blir opprettet og brukt i programmer, og bruker den type informasjonen som en guide for å få fart på ting. For eksempel, hvis en Python-funksjon fungerer med bare en eller to forskjellige objekttyper, genererer PyPy maskinkode for å håndtere de spesifikke tilfellene.

PyPys optimaliseringer håndteres automatisk ved kjøretid, så du trenger vanligvis ikke å justere ytelsen. En avansert bruker kan eksperimentere med PyPys kommandolinjealternativer for å generere raskere kode for spesielle tilfeller, men bare sjelden er dette nødvendig.

PyPy avviker også fra måten CPython håndterer noen interne funksjoner, men prøver å bevare kompatibel oppførsel. For eksempel håndterer PyPy søppelinnsamling annerledes enn CPython. Ikke alle objekter samles umiddelbart når de kommer utenfor omfanget, så et Python-program som kjører under PyPy kan vise et større minnefotavtrykk enn når det kjører under CPython. Men du kan fremdeles bruke Pythons høykvalitets søppelinnsamlingskontroller som er utsatt gjennom gc modul, for eksempel gc.enable (), gc.disable (), og gc.collect ().

Hvis du vil ha informasjon om PyPys JIT-oppførsel ved kjøretid, inkluderer PyPy en modul, pypyjit, som utsetter mange JIT-kroker til Python-applikasjonen. Hvis du har en funksjon eller modul som ser ut til å fungere dårlig med JIT, pypyjit lar deg få detaljert statistikk om det.

En annen PyPy-spesifikk modul, __pypy__, avslører andre funksjoner som er spesifikke for PyPy, så kan være nyttige for å skrive apper som utnytter disse funksjonene. På grunn av Pythons kjøretidsdynamikk er det mulig å konstruere Python-apper som bruker disse funksjonene når PyPy er tilstede og ignorerer dem når det ikke er det.

PyPy-begrensninger

Magisk som PyPy kan virke, det er ikke magisk. PyPy har visse begrensninger som reduserer eller reduserer effektiviteten for visse typer programmer. Akk, PyPy er ikke en helt universell erstatning for aksjen CPython kjøretid.

PyPy fungerer best med rene Python-apper

PyPy har alltid prestert best med “rene” Python-applikasjoner - dvs. applikasjoner skrevet i Python og ingenting annet. Python-pakker som grensesnittet med C-biblioteker, for eksempel NumPy, har ikke gått like bra på grunn av måten PyPy emulerer CPythons opprinnelige binære grensesnitt.

PyPys utviklere har gjort noe med dette problemet, og gjort PyPy mer kompatibel med de fleste Python-pakker som er avhengige av C-utvidelser. Numpy, for eksempel, fungerer veldig bra med PyPy nå. Men hvis du vil ha maksimal kompatibilitet med C-utvidelser, bruk CPython.

PyPy fungerer best med programmer som kjører lenger

En av bivirkningene av hvordan PyPy optimaliserer Python-programmer, er at programmer med lengre drift har størst nytte av optimaliseringen. Jo lenger programmet kjører, jo mer informasjon om kjøretidstype kan PyPy samle, og jo flere optimaliseringer kan det gjøre. En-og-klare Python-skript vil ikke ha nytte av denne typen ting. Applikasjonene som har nytte, har vanligvis sløyfer som kjører i lange perioder, eller som kjører kontinuerlig i bakgrunnen - for eksempel nettrammer.

PyPy gjør ikke kompilering på forhånd

PyPykompilerer Python-kode, men det er den ikkeen kompilator for Python-kode. På grunn av måten PyPy utfører sine optimaliseringer og den iboende dynamikken til Python, er det ingen måte å sende ut den resulterende JITted-koden som en frittstående binær og bruke den på nytt. Hvert program må settes sammen for hvert løp. Hvis du vil kompilere Python til raskere kode som kan kjøre som en frittstående app, kan du bruke Cython, Numba eller det nåværende eksperimentelle Nuitka-prosjektet.

$config[zx-auto] not found$config[zx-overlay] not found