Što je Cython? Python brzinom C

Python je na glasu kao jedan od najprikladnijih, bogato opremljenih i nadasve korisnih programskih jezika. Brzina izvršenja? Ne tako puno.

Uđite u Cython. Jezik Cython super je skup Pythona koji se kompajlira u C, dajući povećanja performansi koja se mogu kretati od nekoliko posto do nekoliko redova veličine, ovisno o zadatku. Za posao koji je ograničen Pythonovim izvornim vrstama objekata, ubrzavanja neće biti velika. Ali za numeričke operacije, ili bilo koje druge operacije koje ne uključuju Pythonove vlastite interijere, dobitak može biti ogroman. 

Uz Cython možete zaobići mnoga Pythonova nativna ograničenja ili ih u potpunosti nadići - bez potrebe da se odričete Pythonove lakoće i praktičnosti. U ovom ćemo članku proći kroz osnovne koncepte iza Cythona i stvoriti jednostavnu Python aplikaciju koja koristi Cython za ubrzavanje jedne od svojih funkcija.

Povezani video: Korištenje Cythona za ubrzavanje Pythona

Sastavite Python u C

Python kôd može upućivati ​​pozive izravno u C module. Ti C moduli mogu biti ili generičke C knjižnice ili knjižnice izgrađene posebno za rad s Pythonom. Cython generira drugu vrstu modula: C knjižnice koje razgovaraju s Pythonovim internim mrežama i koje se mogu kombinirati sa postojećim Python kodom.

Cython kôd po izgledu izgleda mnogo poput Python koda. Ako hranite Cython kompajler programom Python (podržani su i Python 2.x i Python 3.x), Cython će ga prihvatiti onakvog kakav jest, ali niti jedno Cythonovo matično ubrzanje neće doći u obzir. Ali ako Python kôd ukrasite oznakama tipa u Cythonovoj posebnoj sintaksi, Cython će moći zamijeniti brze C ekvivalente sporim Python objektima.

Imajte na umu da je Cythonov pristup  inkrementalni . To znači da programer može započeti s  postojećom aplikacijom Python i ubrzati je izmjenama koda, umjesto da cijelu aplikaciju prepiše iz temelja.

Ovaj se pristup općenito poklapa s prirodom problema s izvedbom softvera. U većini programa velika većina CPU intenzivnog koda koncentrirana je na nekoliko vrućih točaka - inačici Pareto principa, poznatom i kao pravilo "80/20". Stoga veći dio koda u Python aplikaciji ne treba optimizirati performanse, već samo nekoliko kritičnih dijelova. Te vruće točke možete postupno prevesti u Cython i tako postignite potrebne performanse tamo gdje je najvažnije. Ostatak programa može ostati u Pythonu radi udobnosti programera.

Kako koristiti Cython

Razmotrite sljedeći kod preuzet iz Cythonove dokumentacije:

def f (x):

    povrat x ** 2-x

def integrate_f (a, b, N):

    s = 0

    dx = (ba) / N

    za i u opsegu (N):

        s + = f (a + i * dx)

    povratak s * dx

Ovo je primjer igračke, ne baš učinkovita provedba integralne funkcije. Kao čisti Python kôd, spor je, jer Python mora pretvoriti naprijed-natrag između numeričkih tipova koji su izvorni za stroj i vlastitih unutarnjih tipova objekata.

Sada razmotrite Cython verziju istog koda, s podcrtanim Cythonovim dodacima:

 cdef dvostruki f (dvostruki x):

    povrat x ** 2-x

def integrate_f (dvostruki a, dvostruki b, int N):

    cdef int i

    cdef dvostruki s, x, dx

    s = 0

    dx = (ba) / N

    za i u opsegu (N):

        s + = f (a + i * dx)

    povratak s * dx

Ako izričito proglasiti vrste varijabli, i za funkciju parametara i varijabli korištenih u tijelu funkcije ( double, intitd), Cython će se prevesti sve to u C. Također možemo koristiti cdefključne riječi za definiranje funkcije koje su implementiran prvenstveno u C za dodatnu brzinu, iako te funkcije mogu pozvati samo druge Cython funkcije, a ne i Python skripte. (U gornjem primjeru, integrate_fmože ih pozvati samo druga Python skripta.)

Primijetite kako se malo promijenio naš stvarni  kod . Sve što smo učinili je dodati deklaracije tipa postojećem kodu kako bismo postigli značajan napredak u izvedbi.

Cython prednosti

Osim što može ubrzati kôd koji ste već napisali, Cython daje još nekoliko prednosti:

Rad s vanjskim C knjižnicama može biti brži

Python paketi poput NumPy omotavaju C knjižnice u Python sučelja kako bi im olakšali rad. Međutim, kretanje između Pythona i C kroz te omote može usporiti stvari. Cython vam omogućuje da izravno razgovarate s temeljnim knjižnicama, bez Pythona na putu. (Podržane su i knjižnice C ++.)

Možete koristiti i C i Python upravljanje memorijom

Ako koristite Python objekte, njima se upravlja memorijom i prikuplja smeće isto kao i u običnom Pythonu. Ali ako želite stvoriti i upravljati vlastitim strukturama na razini C i koristiti malloc/ freeraditi s njima, to možete učiniti. Sjetite se samo počistiti za sobom.

Prema potrebi možete se odlučiti za sigurnost ili brzinu 

Cython automatski izvodi runtime provjere uobičajenih problema koji se pojavljuju u C-u, kao što je pristup izvan granica niza, putem dekoratora i direktiva kompajlera (npr. @boundscheck(False)). Slijedom toga, C kôd koji generira Cython prema zadanim je postavkama mnogo sigurniji od ručno valjanog C koda, iako potencijalno po cijenu neobrađenih performansi.

Ako ste sigurni da vam neće trebati te provjere tijekom izvođenja, možete ih onemogućiti za dodatno povećanje brzine, bilo na cijelom modulu ili samo na odabranim funkcijama.

Cython vam također omogućuje nativni pristup Python strukturama koje koriste protokol međuspremnika za izravan pristup podacima pohranjenim u memoriji (bez posrednog kopiranja). Cythonovi pregledi memorije omogućuju vam rad s tim strukturama velikom brzinom i s razinom sigurnosti koja odgovara zadatku. Na primjer, sirovi podaci koji stoje u osnovi Python niza mogu se čitati na ovaj način (brzo) bez potrebe da se prolazi kroz Python runtime (sporo).

Kôd Cython C može imati koristi od izdavanja GIL-a

Pythonova globalna brava tumača ili GIL sinkronizira niti unutar interpretatora, štiteći pristup Python objektima i upravljajući prepirkom za resurse. No, GIL je često kritiziran kao kamen spoticanja za Python s boljom izvedbom, posebno na višejezgrenim sustavima.

Ako imate odjeljak koda koji se ne poziva na Python objekte i izvodi dugotrajnu operaciju, možete ga označiti  with nogil:direktivom kako biste omogućili pokretanje bez GIL-a. To oslobađa Python tumač da radi i druge stvari, a Cython kodu omogućuje upotrebu više jezgri (uz dodatni rad).

Cython može koristiti sintaksu nagovještaja tipa Python 

Python ima sintaksu nagovještavanja tipa koju uglavnom koriste linteri i provjerivači koda, a ne CPython interpreter. Cython ima vlastitu prilagođenu sintaksu za ukrase koda, ali s nedavnim revizijama Cythona možete koristiti sintaksu nagovještavanja tipa Python kako biste pružili osnovne savjete o tipu i Cythonu. 

Cython se može koristiti za prikrivanje osjetljivog Python koda

Python module je trivijalno lako dekompilirati i pregledati, ali kompilirani binarni programi to nisu. Kada distribuirate aplikaciju Python krajnjim korisnicima, ako želite zaštititi neke od njenih modula od slučajnog pregledavanja, to možete učiniti kompajliranjem s Cythonom. No, imajte na umu da je ovo nuspojava Cythonovih mogućnosti, a ne jedna od zadanih funkcija.

Ograničenja citona

Imajte na umu da Cython nije čarobni štapić. Ne pretvara automatski svaku instancu poky Python koda u brzi C kod. Da biste Cython iskoristili na najbolji mogući način, morate ga pametno koristiti - i razumjeti njegova ograničenja:

Malo ubrzavanja konvencionalnog Python koda

Kad Cython nađe Python kôd, ne može ga u potpunosti prevesti u C, transformira ga u niz C poziva na Pythonove unutarnje dijelove. To znači izbacivanje Pythonovog tumača iz izvršne petlje, što kodu zadaje skromnu brzinu od 15 do 20 posto. Imajte na umu da je ovo najbolji slučaj; u nekim situacijama možda nećete vidjeti poboljšanje performansi ili čak pogoršanje performansi.

Malo ubrzanje za matične Python strukture podataka

Python nudi mnoštvo struktura podataka - nizove, popise, korice, rječnike itd. Izuzetno su prikladni za programere i dolaze sa vlastitim automatskim upravljanjem memorijom. Ali oni su sporiji od čistog C.

Cython vam omogućuje da i dalje koristite sve Python strukture podataka, iako bez puno ubrzanja. To je, opet, zato što Cython jednostavno poziva C API-je u Python vrijeme izvođenja koji stvaraju i manipuliraju tim objektima. Stoga se Python strukture podataka ponašaju slično kao Python kod optimiziran za Cython: Ponekad vam se pojača, ali samo malo. Za najbolje rezultate koristite C varijable i strukture. Dobra vijest je da Cython olakšava rad s njima.

Cython kôd radi najbrže kada je "čisti C"

Ako imate funkciju u C označenu s cdefključnom riječi, sa svim njezinim varijablama i ugrađenim pozivima funkcije na druge stvari koje su čisti C, ona će se pokretati onoliko brzo koliko C može ići. Ali ako se ta funkcija poziva na bilo koji Python izvorni kôd, poput strukture podataka Pythona ili poziva na interni Python API, taj će poziv biti usko grlo u izvedbi.

Srećom, Cython nudi način da uočite ova uska grla: izvješće izvornog koda koje na prvi pogled pokazuje koji su dijelovi vaše Cython aplikacije čisti C i koji dijelovi komuniciraju s Pythonom. Što je aplikacija optimizirana, to će manje interakcije biti s Pythonom.

Cython NumPy 

Cython poboljšava upotrebu biblioteka za drobljenje brojeva trećih strana na bazi C, poput NumPy. Budući da se Cython kod kompajlira u C, on može izravno komunicirati s tim knjižnicama i izvaditi Pythonova uska grla iz petlje.

Ali NumPy, posebno, dobro radi s Cythonom. Cython ima izvornu podršku za određene konstrukcije u NumPyu i pruža brz pristup NumPy nizovima. A ista poznata NumPy sintaksa koju biste koristili u konvencionalnoj Python skripti može se koristiti i u Cythonu takva kakva jest.

Međutim, ako želite stvoriti najbliže moguće veze između Cythona i NumPy-a, morate dodatno ukrasiti kod Cythonovom prilagođenom sintaksom. cimportIzjava, na primjer, omogućuje Cython kod vidjeti C-razini konstrukti u knjižnicama u vrijeme prevođenja za najbrže moguće vezova.

Budući da se NumPy toliko koristi, Cython podržava NumPy "izvan okvira". Ako imate instaliran NumPy, možete samo navesti  cimport numpy svoj kôd, a zatim dodati daljnji ukras da biste koristili izložene funkcije. 

Cython profiliranje i izvedba

Najbolje performanse bilo kojeg dijela koda dobivate tako da ga profilirate i iz prve ruke vidite gdje su uska grla. Cython nudi kuke za Pythonov modul cProfile, tako da možete koristiti vlastite Pythonove alate za profiliranje, poput cProfile, da biste vidjeli kako se izvodi vaš Cython kôd. 

U svim slučajevima pomaže se sjetiti da Cython nije magija - da se i dalje primjenjuju razumne prakse u stvarnom svijetu. Što manje prelazite između Pythona i Cythona, to će vaša aplikacija brže raditi.

Na primjer, ako imate zbirku objekata koje želite obraditi u Cythonu, nemojte ih prevrtati u Pythonu i pozivati ​​Cython funkciju u svakom koraku. Proslijedite cijelu kolekciju vašem Cython modulu i tamo ponovite. Ova se tehnika često koristi u knjižnicama koje upravljaju podacima, pa je dobar model za oponašanje vlastitog koda.

Koristimo Python jer pruža praktičnost programera i omogućuje brzi razvoj. Ponekad ta produktivnost programera košta cijenu izvedbe. Uz Cython, samo malo dodatnog napora može vam pružiti najbolje od oba svijeta.

Pročitajte više o Pythonu

  • Što je Python? Moćno, intuitivno programiranje
  • Što je PyPy? Brži Python bez boli
  • Što je Cython? Python brzinom C
  • Vodič za Cython: Kako ubrzati Python
  • Kako instalirati Python na pametan način
  • Najbolje nove značajke u Pythonu 3.8
  • Bolje upravljanje Python projektima s poezijom
  • Virtualenv i venv: Objašnjena Python virtualna okruženja
  • Python virtualenv i venv čine i ne čine
  • Objašnjeni Python navoji i potprocesi
  • Kako se koristi Python program za ispravljanje pogrešaka
  • Kako koristiti timeit za profiliranje Python koda
  • Kako koristiti cProfile za profiliranje Python koda
  • Započnite s async u Pythonu
  • Kako koristiti asyncio u Pythonu
  • Kako pretvoriti Python u JavaScript (i natrag)
  • Python 2 EOL: Kako preživjeti kraj Pythona 2
  • 12 Pythona za svaku programsku potrebu
  • 24 Python biblioteke za svakog programera Pythona
  • 7 slatkih IDE-a za Python koje ste možda propustili
  • 3 glavna nedostatka Pythona - i njihova rješenja
  • 13 uspoređenih Python web okvira
  • 4 Python test okvira za uništavanje bugova
  • 6 sjajnih novih Python značajki koje ne želite propustiti
  • 5 Python distribucija za svladavanje strojnog učenja
  • 8 sjajnih Python knjižnica za obradu prirodnog jezika