Python je zmogljiv programski jezik, ki se ga je enostavno naučiti in z njim delati, vendar ga ni vedno najhitreje zagnati - še posebej, če se ukvarjate z matematiko ali statistiko. Neposredne knjižnice, kot je NumPy, ki zavijajo knjižnice C, lahko znatno izboljšajo delovanje nekaterih operacij, včasih pa potrebujete samo surovo hitrost in moč C neposredno v Pythonu.
Cython je bil razvit za lažje pisanje razširitev C za Python in omogočanje preoblikovanja obstoječe kode Python v C. Še več, Cython omogoča pošiljanje optimizirane kode z aplikacijo Python brez zunanjih odvisnosti.
V tej vadnici se bomo podali skozi korake, potrebne za preoblikovanje obstoječe kode Pythona v Cython in njeno uporabo v produkcijski aplikaciji.
Sorodni video: Uporaba Cythona za pospešitev Pythona
Primer Cythona
Začnimo s preprostim primerom, povzetim iz Cythonove dokumentacije, ne preveč učinkovitega izvajanja integralne funkcije:
def f (x):vrnitev x ** 2-x
def integrate_f (a, b, N):
s = 0
dx = (b-a) / N
za i v območju (N):
s + = f (a + i * dx)
vrnitev s * dx
Koda je lahko berljiva in razumljiva, vendar deluje počasi. To pa zato, ker mora Python nenehno pretvarjati naprej in nazaj med lastnimi vrstami predmetov in surovimi numeričnimi vrstami stroja.
Zdaj razmislite o različici Cython iste kode s poudarjenimi dodatki Cython:
cdef f (dvojni x):vrnitev x ** 2-x
def integrate_f (dvojni a, dvojni b, int N):
cdef int i
cdef dvojni s, x, dx
s = 0
dx = (b-a) / N
za i v območju (N):
s + = f (a + i * dx)
vrnitev s * dx
Ti dodatki nam omogočajo, da v celotni kodi izrecno razglasimo tipe spremenljivk, tako da lahko prevajalnik Cython te "okrašene" dodatke prevede v C.
Povezani video: Kako Python olajša programiranje
Kot nalašč za IT, Python poenostavlja številne vrste dela, od avtomatizacije sistema do dela na najsodobnejših področjih, kot je strojno učenje.
Sintaksa Cython
Ključnih besed, ki se uporabljajo za okrasitev kode Cython, v običajni sintaksi Python ni. Razviti so bili posebej za Cython, zato nobena koda, okrašena z njimi, ne bo delovala kot običajni program Python.
To so najpogostejši elementi Cythonove sintakse:
Spremenljive vrste
Nekatere vrste spremenljivk, ki se uporabljajo v Cythonu, so odmevi lastnih vrst Pythona, kot je nprint
, plovec
, in dolga
. Druge vrste spremenljivk Cython najdemo tudi v jeziku C, na primer char
ali strukt
, kot so izjave, kot nepodpisano dolgo
. In drugi so edinstveni za Cython, na primer bint
, predstavitev Pythona na ravni C. Pravilno napačno
vrednote.
The cdef
in cpdef
vrste funkcij
The cdef
ključna beseda označuje uporabo vrste Cython ali C. Uporablja se tudi za definiranje funkcij, tako kot v Pythonu.
Funkcije, napisane v Cythonu z uporabo Pythona def
Ključne besede so vidne drugim kodam Pythona, vendar jih je treba kaznovati. Funkcije, ki uporabljajo cdef
Ključne besede so vidne samo drugim kodam Cython ali C, vendar se izvedejo veliko hitreje. Če imate funkcije, ki se prikličejo samo znotraj modula Cython, uporabite cdef
.
Tretja ključna beseda, cpdef
, zagotavlja združljivost s kodo Python in kodo C, tako da lahko koda C s polno hitrostjo dostopa do deklarirane funkcije. To udobje pa stane, vendar:cpdef
funkcije generirajo več kode in imajo nekoliko več režijskih stroškov kot cdef
.
Druge ključne besede Cython
Druge ključne besede v Cythonu zagotavljajo nadzor nad vidiki pretoka in vedenja programa, ki v Pythonu niso na voljo:
gil
innogil
. To so upravljavci konteksta, ki se uporabljajo za razmejitev delov kode, ki zahtevajo (z gil:
) ali ne zahtevajo (z nogil:
) Pythonova Global Interpreter Lock ali GIL. Koda C, ki ne kliče API-ja Python, se lahko hitreje izvaja v anogil
blok, še posebej, če izvaja dolgotrajno operacijo, kot je branje iz omrežne povezave.cimport
. To usmerja Cython na uvoz podatkovnih tipov C, funkcij, spremenljivk in tipov razširitev. Uporabljajo se na primer aplikacije Cython, ki uporabljajo izvirne module C NumPycimport
za dostop do teh funkcij.vključujejo
. To izvorno kodo ene datoteke Cython postavi znotraj druge, podobno kot v C. Upoštevajte, da ima Cython bolj dovršen način za skupno rabo deklaracij med datotekami Cython, ki niso samovključujejo
s.ctypedef
. Uporablja se za sklicevanje na definicije tipov v zunanjih datotekah glave C.zunanjost
. Uporablja se zcdef
za sklicevanje na funkcije C ali spremenljivke, ki jih najdemo v drugih modulih.javno / api
. Uporablja se za podajanje deklaracij v modulih Cython, ki bodo vidne drugim kodam C.v vrsti
. Uporablja se za označevanje dane funkcije, zaradi hitrosti mora biti vstavljena ali pa mora biti njena koda nameščena v telo klicne funkcije, kadar koli se ta uporablja. Na primerf
funkcijo v zgornjem primeru kode lahko okrasimo zv vrsti
, da zmanjša svojo funkcijsko obremenitev, ker se uporablja samo na enem mestu. (Upoštevajte, da lahko prevajalnik C samodejno izvede lastno vstavljanje, vendarv vrsti
vam omogoča izrecno določitev, ali naj bo nekaj vstavljeno.)
Vseh ključnih besed Cython ni treba poznati vnaprej. Koda Cython se običajno piše postopoma - najprej napišete veljavno kodo Python, nato dodate okras Cython, da jo pospešite. Tako lahko po potrebi posnamete razširjeno sintakso ključne besede Cython.
Prevedite Cython
Zdaj, ko imamo nekaj ideje o tem, kako izgleda preprost program Cython in zakaj je videti tako, kot je, pojdimo skozi korake, potrebne za prevajanje Cythona v delujoč binarni sistem.
Za izdelavo delujočega programa Cython bomo potrebovali tri stvari:
- Tolmač Python. Če je mogoče, uporabite najnovejšo različico izdaje.
- Paket Cython. Cython lahko v Python dodate s pomočjo
pip
upravitelj paketov:pip namestite cython
- Prevajalnik C.
Točka št. 3 je lahko zapletena, če za razvojno platformo uporabljate Microsoft Windows. Za razliko od Linuxa Windows nima standardne komponente s prevajalnikom C. Če želite to rešiti, vzemite kopijo Microsoft Visual Studio Community Edition, ki vključuje Microsoftov prevajalnik C in ne stane nič.
Upoštevajte, da je od tega pisanja najnovejša različica Cythona 0.29.16, vendar je na voljo beta različica Cython 3.0. Če uporabljate pip namestite cython
bo nameščena najnovejša različica, ki ni beta. Če želite preizkusiti beta različico, uporabite pip namestite cython> = 3.0a1
namestiti najnovejšo izdajo podružnice Cython 3.0. Razvijalci Cythona priporočajo, da poskusite vejo Cython 3.0, kadar koli je to mogoče, saj v nekaterih primerih ustvari bistveno hitrejšo kodo.
Programi Cython uporabljajo .pyx
končnico datoteke. V novem imeniku ustvarite datoteko z imenom num.pyx
ki vsebuje zgoraj prikazan primer kode Cython (drugi vzorec kode pod »Primer Cython«) in datoteko z imenom main.py
ki vsebuje naslednjo kodo:
iz num uvoz integrate_ftiskanje (integrate_f (1.0, 10.0, 2000))
To je reden Python program, ki bo poklical integrate_f
funkcija najdena vnum.pyx
. Koda Python "vidi" kodo Cython le kot drug modul, zato vam ni treba storiti ničesar drugega, kot da uvozite prevedeni modul in zaženete njegove funkcije.
Na koncu dodajte datoteko z imenom setup.py
z naslednjo kodo:
from distutils.core import setup from distutils.extention import Extension from Cython.Build import cythonize ext_modules = [Razširitev (r'num ', [r'num.pyx']),] setup (name = "num", ext_modules = cythonize (ext_modules),)
setup.py
ga Python običajno uporablja za namestitev modula, s katerim je povezan, lahko pa ga uporabimo tudi za usmerjanje Pythona k prevajanju razširitev C za ta modul. Tukaj uporabljamo setup.py
za prevajanje kode Cython.
Če uporabljate Linux in imate nameščen prevajalnik C (običajno v tem primeru), lahko prevedete .pyx
datoteko v C z zagonom ukaza:
python setup.py build_ext --inplace
Če uporabljate Microsoft Windows in Microsoft Visual Studio 2017 ali novejšo različico, se prepričajte, da imate najnovejšo različico setuptools
nameščen v Pythonu (različica 46.1.3 od tega pisanja), preden bo ta ukaz deloval. To zagotavlja, da bodo Pythonova orodja za gradnjo lahko samodejno zaznala in uporabila različico Visual Studio, ki ste jo namestili.
Če je prevajanje uspešno, se bodo v imeniku prikazale nove datoteke: številka c
(datoteko C, ki jo je ustvaril Cython) in datoteko z ali .o
razširitev (na Linuxu) ali a .pyd
(v sistemu Windows). To je binarna datoteka, v katero je bila prevedena datoteka C. Morda boste videli tudi \ graditi
podimenik, ki vsebuje artefakte iz postopka gradnje.
Teči python main.py
, in kot odgovor bi morali videti nekaj takega:
283.297530375
To je rezultat prevedene integralne funkcije, kot jo prikliče naša čista koda Python. Poskusite se igrati s parametri, ki so bili posredovani funkciji v main.py
da vidim, kako se spremeni izhod.
Upoštevajte, da kadar koli spremenite .pyx
datoteko, jo boste morali znova sestaviti. (Vse spremembe običajne kode Python začnejo veljati takoj.)
Nastala prevedena datoteka nima odvisnosti, razen različice Pythona, za katero je bila prevedena, zato jo je mogoče združiti v binarno kolo. Če se v svoji kodi sklicujete na druge knjižnice, na primer NumPy (glejte spodaj), jih boste morali navesti kot del zahtev aplikacije.
Kako uporabljati Cython
Zdaj, ko veste, kako "cythonize" del kode, je naslednji korak določiti, kako lahko vaša aplikacija Python koristi Cython. Kje natančno bi ga morali uporabiti?
Za najboljše rezultate uporabite Cython za optimizacijo tovrstnih funkcij Pythona:
- Funkcije, ki se izvajajo v tesnih zankah ali zahtevajo veliko časa obdelave v enem samem "vročem mestu" kode.
- Funkcije, ki izvajajo numerične manipulacije.
- Funkcije, ki delujejo z objekti, ki jih je mogoče predstaviti v čistem C, kot so osnovni številski tipi, nizi ali strukture, namesto vrst objektov Python, kot so seznami, slovarji ali nabori.
Python je bil tradicionalno manj učinkovit pri zankah in numeričnih manipulacijah kot drugi jeziki, ki niso interpretirani. Bolj ko okrasite kodo, da označuje, da mora uporabljati osnovne številske vrste, ki jih lahko spremenite v C, hitreje bo stiskal številke.
Uporaba vrst objektov Python v Cythonu sama po sebi ni problem. Funkcije Cython, ki uporabljajo predmete Python, se bodo še vedno prevajale, predmeti Python pa bodo morda bolj zaželeni, če uspešnost ni najbolj pomembna. Toda vsaka koda, ki uporablja objekte Python, bo omejena z zmogljivostjo izvajalnega okolja Python, saj bo Cython ustvaril kodo za neposreden naslov Pythonovih API-jev in ABI-jev.
Še en vreden cilj optimizacije Cython je koda Python, ki neposredno komunicira s knjižnico C. Kodo Python "ovoj" lahko preskočite in se neposredno povežete s knjižnicami.
Vendar Cython to počnene samodejno ustvari ustrezne klicne vmesnike za te knjižnice. Cython se bo moral sklicevati na podpise funkcij v zaglavnih datotekah knjižnice s pomočjo cdef extern iz
izjavo. Če nimate datotek z glavo, Cython odpušča dovolj, da lahko prijavite podpise zunanjih funkcij, ki se približajo prvotnim glavam. Kadar je le mogoče, pa izvirnike uporabljajte na varnem.
Ena zunanja knjižnica C, ki jo Cython lahko uporabi takoj, je NumPy. Če želite izkoristiti hiter dostop Cythona do nizov NumPy, uporabite cimport numpy
(neobvezno z kot np
da ostane njegov imenski prostor ločen) in nato uporabite cdef
izjave za deklariranje spremenljivk NumPy, kot je cdef np.array
ali np.ndarray
.
Cython profiliranje
Prvi korak k izboljšanju učinkovitosti aplikacije je njeno profiliranje - ustvarjanje podrobnega poročila o tem, kje je čas porabljen med izvajanjem. Python ponuja vgrajene mehanizme za ustvarjanje kodnih profilov. Cython se ne samo vključi v te mehanizme, temveč ima tudi lastna orodja za profiliranje.
Pythonov lastni profiler, cProfile
, generira poročila, ki prikazujejo, katere funkcije v danem programu Python zavzamejo največ časa. Koda Cython privzeto ni prikazana v teh poročilih, lahko pa omogočite profiliranje kode Cython, tako da na vrh strani vstavite direktivo o prevajalniku. .pyx
datoteka s funkcijami, ki jih želite vključiti v profiliranje:
# cython: profile = True
Omogočite lahko tudi sledenje po vrsticah na kodi C, ki jo ustvari Cython, vendar to pomeni veliko režijskih stroškov in je zato privzeto izklopljeno.
Upoštevajte, da profiliranje zahteva uspešnost, zato obvezno izključite profiliranje za kodo, ki je poslana v proizvodnjo.
Cython lahko ustvari tudi poročila o kodi, ki kažejo, koliko danega .pyx
datoteka se pretvori v C, koliko pa ostane koda Python. Če želite to videti v akciji, uredite setup.py
v našem primeru in na vrh dodajte naslednji dve vrstici:
uvoz Cython.Compiler.OptionsCython.Compiler.Options.annotate = True
(Lahko tudi uporabite direktivo v setup.py, da omogočite pripise, vendar je z zgornjo metodo pogosto lažje delati.)
Izbrišite .c
datoteke, ustvarjene v projektu, in znova zaženite datoteko setup.py
skript, da vse prevede. Ko končate, bi morali v istem imeniku videti datoteko HTML, ki deli ime datoteke .pyx - v tem primerunum.html
. Odprite datoteko HTML in videli boste dele kode, ki so še vedno odvisni od Pythona, označene z rumeno. Kliknite rumena območja in si oglejte osnovno kodo C, ki jo je ustvaril Cython.