Programiranje

Vadnica za Cython: Kako pospešiti Python

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 in nogil. 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 a nogil blok, še posebej, če izvaja dolgotrajno operacijo, kot je branje iz omrežne povezave.
  • cimportTo usmerja Cython na uvoz podatkovnih tipov C, funkcij, spremenljivk in tipov razširitev. Uporabljajo se na primer aplikacije Cython, ki uporabljajo izvirne module C NumPy cimport 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 samo vključujejos.
  • ctypedef. Uporablja se za sklicevanje na definicije tipov v zunanjih datotekah glave C.
  • zunanjost. Uporablja se z cdef 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 primer f funkcijo v zgornjem primeru kode lahko okrasimo z v vrsti , da zmanjša svojo funkcijsko obremenitev, ker se uporablja samo na enem mestu. (Upoštevajte, da lahko prevajalnik C samodejno izvede lastno vstavljanje, vendar v 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:

  1. Tolmač Python. Če je mogoče, uporabite najnovejšo različico izdaje.
  2. Paket Cython. Cython lahko v Python dodate s pomočjo pip upravitelj paketov: pip namestite cython
  3. 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 cythonbo 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_f

tiskanje (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:

  1. Funkcije, ki se izvajajo v tesnih zankah ali zahtevajo veliko časa obdelave v enem samem "vročem mestu" kode.
  2. Funkcije, ki izvajajo numerične manipulacije.
  3. 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.Options

Cython.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.

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