Programavimas

Kas yra „Cython“? Python C greičiu

„Python“ turi gerą reputaciją, nes yra viena patogiausių, gausiai įrengtų ir tiesiog naudingų programavimo kalbų. Vykdymo greitis? Ne tiek jau daug.

Įveskite „Cython“. „Cython“ kalba yra „Python“ viršutinis rinkinys, kompiliuojamas į C, užtikrinantis našumą, kuris gali svyruoti nuo kelių procentų iki kelių dydžių, atsižvelgiant į atliekamą užduotį. Darbų, kuriuos suriša „Python“ vietiniai objektų tipai, greičiai nebus dideli. Tačiau atliekant skaitines operacijas ar bet kokias operacijas, nesusijusias su paties „Python“ vidumi, nauda gali būti didžiulė.

Naudodami „Cython“ galite užkirsti kelią daugeliui vietinių „Python“ apribojimų arba visiškai juos peržengti - neatsisakydami „Python“ patogumo ir patogumo. Šiame straipsnyje mes apžvelgsime pagrindines „Cython“ koncepcijas ir sukursime paprastą „Python“ programą, kuri naudoja „Cython“, kad pagreitintų vieną iš jo funkcijų.

Susijęs vaizdo įrašas: „Cython“ naudojimas norint pagreitinti „Python“

Sudarykite „Python“ į „C“

„Python“ kodas gali skambinti tiesiai į C modulius. Tie C moduliai gali būti arba bendrosios C bibliotekos, arba bibliotekos, specialiai sukurtos darbui su Python. „Cython“ generuoja antros rūšies modulį: C bibliotekos, kurios kalba su „Python“ vidiniais elementais ir kurias galima susieti su esamu „Python“ kodu.

„Cython“ kodas pagal savo dizainą atrodo labai panašus į „Python“ kodą. Jei tiekiate „Cython“ kompiliatorių „Python“ programa (palaikomi ir „Python 2.x“, ir „Python 3.x“), „Cython“ priims ją tokią, kokia yra, tačiau nė vienas iš vietinių „Cython“ pagreitinimų nebus įjungtas. Bet jei „Python“ kodą papuošite specialios „Cython“ sintaksės tipo anotacijomis, „Cython“ galės lėtus „Python“ objektus pakeisti greitais C ekvivalentais.

Atkreipkite dėmesį, kad Cython požiūris yraInkrementinis. Tai reiškia, kad kūrėjas gali pradėti nuoesamas „Python“ programą ir pagreitinkite ją atlikdami kodo pakeitimus vietoje to, kad perrašytumėte visą programą iš pagrindų.

Šis požiūris suderinamas su programinės įrangos našumo problemų pobūdžiu. Daugumoje programų didžioji dalis procesoriaus reikalaujančio kodo yra sutelkta keliose vietose - „Pareto“ principo versija, dar vadinama „80/20“ taisykle. Taigi daugumos „Python“ programos kodo nereikia optimizuoti pagal našumą, tik keletą kritinių dalių. Galite palaipsniui išversti šias karštuosius taškus į „Cython“ ir taip gauti reikiamą našumą ten, kur tai svarbiausia. Likusi programos dalis gali likti „Python“ programuotojų patogumui.

Kaip naudotis „Cython“

Apsvarstykite šį kodą, paimtą iš „Cython“ dokumentų:

def f (x):

grįžti x ** 2-x

def integrate_f (a, b, N):

s = 0

dx = (b-a) / N

i diapazone (N):

s + = f (a + i * dx)

grįžti s * dx

Tai žaislų pavyzdys, ne itin efektyvus integralios funkcijos įgyvendinimas. Kaip grynas „Python“ kodas, jis yra lėtas, nes „Python“ turi konvertuoti pirmyn ir atgal tarp mašininių skaitinių tipų ir savo vidinių objektų tipų.

Dabar apsvarstykite to paties kodo „Cython“ versiją, pabrėždami „Cython“ papildymus:

 cdef dvigubas f (dvigubas x):

grįžti x ** 2-x

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

cdef int

cdef dvigubas s, x, dx

s = 0

dx = (b-a) / N

i diapazone (N):

s + = f (a + i * dx)

grįžti s * dx

Jei mes aiškiai deklaruosime kintamųjų tipus, tiek funkcijos parametrams, tiek kintamiesiems, naudojamiems funkcijos tekste (dvigubai, tarptir kt.), „Cython“ visa tai išvers į C. Mes taip pat galime naudoti cdef raktinis žodis, norint apibrėžti funkcijas, kurios pirmiausia įgyvendinamos C, kad būtų pasiektas papildomas greitis, nors tas funkcijas gali iškviesti tik kitos „Cython“ funkcijos, o ne „Python“ scenarijai. (Tik aukščiau pateiktame pavyzdyje integruoti_f galima iškviesti kitu „Python“ scenarijumi.)

Atkreipkite dėmesį, kiek mažai mūsų faktiniskodas pasikeitė. Viskas, ką mes padarėme, yra pridėti esamų kodų tipo deklaracijas, kad gautume reikšmingą našumą.

„Cython“ privalumai

Be galimybės pagreitinti jau parašytą kodą, „Cython“ suteikia keletą kitų privalumų:

Darbas su išorinėmis C bibliotekomis gali būti greitesnis

„Python“ paketai, pvz., „NumPy“, apgaubia C bibliotekas „Python“ sąsajose, kad su jomis būtų lengva dirbti. Tačiau einant pirmyn ir atgal tarp „Python“ ir „C“ per tuos įvyniojimo įrankius viskas gali sulėtėti. „Cython“ leidžia kalbėti tiesiogiai su pagrindinėmis bibliotekomis, netrukdant „Python“. (Taip pat palaikomos C ++ bibliotekos.)

Galite naudoti tiek C, tiek „Python“ atminties valdymą

Jei naudojate „Python“ objektus, jie yra valdomi atmintyje ir surenkami į šiukšles taip pat, kaip ir įprastame „Python“. Bet jei norite sukurti ir valdyti savo C lygio struktūras ir naudoti malloc/Laisvas dirbti su jais galite tai padaryti. Tik nepamirškite apsivalyti po savęs.

Jei reikia, galite pasirinkti saugumą ar greitį

„Cython“ atlieka dekoratorių ir kompiliatorių nurodymus (pvz., „C“ iškylančių dažniausiai pasitaikančių problemų, pvz., Masyvo išorinės prieigos, vykdymą). @boundscheck (False)). Vadinasi, „Cython“ sugeneruotas C kodas yra daug saugesnis nei numatytasis „C“ kodas, nors ir gali kainuoti neapdorotas našumas.

Jei esate įsitikinę, kad jums nereikės šių patikrų vykdymo metu, galite jas išjungti, kad padidintumėte greitį visame modulyje arba tik pasirinktose funkcijose.

„Cython“ taip pat leidžia jums natūraliai pasiekti „Python“ struktūras, kurios naudoja buferinį protokolą tiesioginei prieigai prie atmintyje saugomų duomenų (be tarpinio kopijavimo). „Cython“ atmintinės leidžia jums dirbti su tomis konstrukcijomis dideliu greičiu ir su užduotį atitinkančiu saugos lygiu. Pavyzdžiui, neapdorotus „Python“ eilutės duomenis galima nuskaityti tokiu būdu (greitai), nereikia pereiti per „Python“ vykdymo laiką (lėtas).

„Cython C“ kodas gali būti naudingas išleidus GIL

„Python's Global Interpreter Lock“ arba GIL sinchronizuoja vertėjo gijas, apsaugodama prieigą prie „Python“ objektų ir valdydama ginčus dėl išteklių. Tačiau GIL buvo plačiai kritikuojamas kaip kliūtis geriau veikiančiam „Python“, ypač daugiagyslėse sistemose.

Jei turite kodo skyrių, kuriame nėra jokių nuorodų į „Python“ objektus ir atliekate ilgai trunkančią operaciją, galite pažymėti jįsu nogil: direktyvą leisti jai veikti be GIL. Tai atlaisvina „Python“ vertėją atlikti kitus veiksmus ir leidžia „Cython“ kodui panaudoti kelis branduolius (su papildomu darbu).

„Cython“ gali naudoti „Python“ tipo užuominų sintaksę

„Python“ turi tipų užuominų sintaksę, kurią daugiausia naudoja nevisų „CPython“ vertėjas, bet sąsajos ir kodų tikrintuvai. „Cython“ turi savo pasirinktinę kodų dekoracijų sintaksę, tačiau su naujausiomis „Cython“ versijomis galite naudoti „Python“ tipo užuominų sintaksę, kad „Cython“ taip pat pateiktų pagrindinius tipo patarimus.

„Cython“ gali būti naudojamas uždengti jautrų „Python“ kodą

„Python“ modulius yra be galo lengva dekompiliuoti ir patikrinti, tačiau kompiliuotus dvejetainius failus - ne. Platindami „Python“ programą galutiniams vartotojams, jei norite apsaugoti kai kuriuos jos modulius nuo atsitiktinio šnipinėjimo, galite tai padaryti sukompiliavę juos su „Cython“. Tačiau atkreipkite dėmesį, kad tai yra šalutinis poveikis „Cython“ galimybių, o ne viena iš numatytų funkcijų.

„Cython“ apribojimai

Turėkite omenyje, kad „Cython“ nėra stebuklinga lazdelė. Tai automatiškai nepaverčia kiekvieno keisto „Python“ kodo egzemplioriaus greitai besikeičiančiu C kodu. Norėdami kuo geriau išnaudoti „Cython“, turite jį naudoti protingai ir suprasti jo apribojimus:

Mažas spartinimas įprastam „Python“ kodui

Kai „Cython“ susiduria su „Python“ kodu, jis negali visiškai išversti į C, jis paverčia šį kodą į „C“ skambučių į „Python“ vidinius elementus seriją. Tai reiškia, kad „Python“ vertėjas išimamas iš vykdymo ciklo, o tai suteikia kodui kuklų 15–20 procentų pagreitį pagal numatytuosius nustatymus. Atkreipkite dėmesį, kad tai yra geriausias scenarijus; kai kuriose situacijose galite nepastebėti jokio našumo ar net blogėti.

Nedaug pagreitina vietinių „Python“ duomenų struktūras

„Python“ pateikia daugybę duomenų struktūrų - eilutes, sąrašus, rinkinius, žodynus ir pan. Jie yra labai patogūs kūrėjams ir turi savo automatinį atminties valdymą. Bet jie yra lėtesni nei grynas C.

„Cython“ leidžia jums ir toliau naudoti visas „Python“ duomenų struktūras, nors ir be didesnio spartinimo. Tai vėlgi, nes „Cython“ tiesiog iškviečia C API „Python“ vykdymo metu, kurie sukuria ir valdo tuos objektus. Taigi „Python“ duomenų struktūros elgiasi panašiai kaip „Cython“ optimizuotas „Python“ kodas paprastai: kartais jūs gaunate pagreitį, bet tik nedaug. Norėdami gauti geriausius rezultatus, naudokite C kintamuosius ir struktūras. Geros naujienos yra tai, kad „Cython“ leidžia lengvai dirbti su jais.

„Cython“ kodas veikia greičiausiai, kai „grynas C“

Jei turite funkciją C, pažymėtą cdef raktinis žodis su visais kintamaisiais ir tiesioginių funkcijų iškvietimais į kitus dalykus, kurie yra grynas C, jis veiks taip greitai, kaip gali C. Bet jei ši funkcija nurodo bet kurį „Python“ gimtąjį kodą, pvz., „Python“ duomenų struktūrą arba iškvietimą į vidinę „Python“ API, tas iškvietimas bus našumas.

Laimei, „Cython“ pateikia būdą pastebėti šias kliūtis: šaltinio kodo ataskaitą, kuri iš pirmo žvilgsnio parodo, kurios jūsų „Cython“ programos dalys yra grynos C ir kurios sąveikauja su „Python“. Kuo geriau optimizuota programa, tuo mažiau bus sąveikos su „Python“.

„Cython NumPy“

„Cython“ pagerina C pagrindu veikiančių trečiųjų šalių skaičių kaupiančių bibliotekų, tokių kaip „NumPy“, naudojimą. Kadangi „Cython“ kodas kompiliuojamas į C, jis gali tiesiogiai sąveikauti su tomis bibliotekomis ir pašalinti „Python“ kliūtis iš kilpos.

Tačiau „NumPy“ ypač gerai veikia su „Cython“. „Cython“ palaiko specifines „NumPy“ konstrukcijas ir suteikia greitą prieigą prie „NumPy“ masyvų. „Cython“ yra tokia pati, kokia yra įprasta „NumPy“ sintaksė, kurią naudosite įprastame „Python“ scenarijuje.

Tačiau, jei norite sukurti kuo glaudesnius „Cython“ ir „NumPy“ susiejimus, turite toliau papuošti kodą pasirinktine „Cython“ sintakse.cimportas Pavyzdžiui, sakinys leidžia „Cython“ kodui matyti C lygio konstrukcijas bibliotekose kompiliavimo metu, kad būtų galima kuo greičiau susieti.

Kadangi „NumPy“ yra taip plačiai naudojamas, „Cython“ palaiko „NumPy“ iš „dėžutės“. Jei turite įdiegtą „NumPy“, galite tiesiog pasakyticimport numpy kodą, tada pridėkite papildomą dekoravimą, kad galėtumėte naudoti eksponuojamas funkcijas.

„Cython“ profiliavimas ir našumas

Geriausias našumas gaunamas iš bet kurio kodo, jį profiliuojant ir iš pirmų rankų matant, kur yra kliūtys. „Cython“ pateikia kablius „Python“ „cProfile“ moduliui, todėl norėdami sužinoti, kaip veikia jūsų „Cython“ kodas, galite naudoti paties „Python“ profiliavimo įrankius, pvz., „CProfile“.

Visais atvejais tai padeda prisiminti, kad „Cython“ nėra magija - vis dar taikoma protinga realaus pasaulio atlikimo praktika. Kuo mažiau judėsite pirmyn ir atgal tarp „Python“ ir „Cython“, tuo greičiau veiks jūsų programa.

Pvz., Jei turite objektų rinkinį, kurį norite apdoroti „Cython“, nekartokite jo „Python“ ir kiekviename žingsnyje iškvieskite „Cython“ funkciją. Praeiti visos kolekcijos į savo „Cython“ modulį ir ten pakartokite. Ši technika dažnai naudojama bibliotekose, tvarkančiose duomenis, todėl tai yra geras modelis, kurį galite mėgdžioti savo kode.

Mes naudojame „Python“, nes tai suteikia programuotojui patogumą ir leidžia greitai tobulėti. Kartais tas programuotojo produktyvumas kainuoja našumo kaina. Su „Cython“ tik šiek tiek papildomų pastangų galite gauti geriausią iš abiejų pasaulių.

Skaitykite daugiau apie „Python“

  • Kas yra „Python“? Galingas, intuityvus programavimas
  • Kas yra PyPy? Greitesnis „Python“ be skausmo
  • Kas yra „Cython“? Python C greičiu
  • „Cython“ pamoka: kaip pagreitinti „Python“
  • Kaip įdiegti „Python“ išmaniuoju būdu
  • Geriausios naujos „Python 3.8“ funkcijos
  • Geresnis „Python“ projektų valdymas naudojant „Poetry“
  • „Virtualenv“ ir „venv“: paaiškintos „Python“ virtualios aplinkos
  • „Python virtualenv“ ir „venv do and donts“
  • Paaiškinta „Python“ sriegimas ir antriniai procesai
  • Kaip naudotis „Python“ derintuvu
  • Kaip naudoti „Timeit“, kad būtų galima nustatyti „Python“ kodą
  • Kaip naudoti „cProfile“ „Python“ kodui nustatyti
  • Pradėkite naudoti „Python“ asinchronizavimą
  • Kaip naudoti „asyncio“ Python
  • Kaip konvertuoti „Python“ į „JavaScript“ (ir dar kartą)
  • „Python 2“ EOL: kaip išgyventi „Python 2“ pabaigą
  • 12 pitonų kiekvienam programavimo poreikiui
  • 24 „Python“ bibliotekos kiekvienam „Python“ kūrėjui
  • 7 mieli „Python“ IDE, kurių galbūt praleidote
  • 3 pagrindiniai „Python“ trūkumai ir jų sprendimo būdai
  • Palyginti 13 „Python“ žiniatinklio sistemų
  • 4 „Python“ testavimo sistemos, kad sutriuškintumėte jūsų klaidas
  • 6 puikios naujos „Python“ funkcijos, kurių nenorite praleisti
  • 5 „Python“ paskirstymai, skirti įsisavinti mašininį mokymąsi
  • 8 puikios „Python“ bibliotekos, skirtos natūraliai kalbai apdoroti