Ohjelmointi

Cython-opetusohjelma: Kuinka nopeuttaa Pythonia

Python on tehokas ohjelmointikieli, joka on helppo oppia ja jonka kanssa on helppo työskennellä, mutta sitä ei aina ole nopein käyttää - varsinkin kun olet matematiikan tai tilastojen parissa. Kolmannen osapuolen kirjastot, kuten NumPy, jotka käärivät C-kirjastoja, voivat parantaa joidenkin toimintojen suorituskykyä merkittävästi, mutta joskus tarvitset vain C: n raakaa nopeutta ja tehoa suoraan Pythonissa.

Cython kehitettiin helpottamaan C-laajennusten kirjoittamista Pythonille ja mahdollistamaan olemassa olevan Python-koodin muuntaminen C: ksi. Lisäksi Cython sallii optimoidun koodin toimituksen Python-sovelluksen kanssa ilman ulkoisia riippuvuuksia.

Tässä opetusohjelmassa käydään läpi vaiheet, jotka ovat tarpeen nykyisen Python-koodin muuntamiseksi Cythoniksi ja sen käyttämiseksi tuotantosovelluksessa.

Aiheeseen liittyvä video: Cythonin käyttäminen Pythonin nopeuttamiseksi

Cython-esimerkki

Aloitetaan yksinkertaisella esimerkillä, joka on otettu Cythonin dokumentaatiosta, integraalin toiminnon ei kovin tehokkaasta toteutuksesta:

def f (x):

paluu x ** 2-x

def integraatio_f (a, b, N):

s = 0

dx = (b-a) / N

i: lle alueella (N):

s + = f (a + i * dx)

palaa s * dx

Koodi on helppo lukea ja ymmärtää, mutta se toimii hitaasti. Tämä johtuu siitä, että Pythonin on jatkuvasti muunnettava edestakaisin omien kohdetyyppiensä ja koneen raakojen numeeristen tyyppien välillä.

Harkitse nyt saman koodin Cython-versiota ja korosta Cythonin lisäykset:

 cdef f (kaksinkertainen x):

paluu x ** 2-x

def integraatio_f (kaksinkertainen a, kaksinkertainen b, int N):

cdef int i

cdef kaksinkertainen s, x, dx

s = 0

dx = (b-a) / N

i: lle alueella (N):

s + = f (a + i * dx)

palaa s * dx

Näiden lisäysten avulla voimme nimenomaisesti ilmoittaa muuttujatyypit koko koodissa, jotta Cython-kääntäjä voi kääntää nämä "koristelut" lisäykset C: ksi.

Liittyvä video: Kuinka Python tekee ohjelmoinnista helpompaa

IT-tekniikalle täydellinen Python yksinkertaistaa monenlaista työtä järjestelmän automaatiosta huipputeknisillä aloilla, kuten koneoppiminen.

Cython-syntakse

Cython-koodin koristeluun käytettyjä avainsanoja ei löydy tavanomaisesta Python-syntaksista. Ne on kehitetty erityisesti Cythonia varten, joten kaikki koristeltu koodit eivät toimi tavallisena Python-ohjelmana.

Nämä ovat Cythonin syntaksin yleisimmät elementit:

Muuttujatyypit

Jotkut Cythonissa käytetyistä muuttujatyypeistä ovat esimerkiksi Pythonin omien tyyppien kaikujaint, kelluaja pitkä. Muut Cython-muuttujatyypit löytyvät myös C: stä, kuten hiiltyä tai rakenne, samoin kuin julkilausumat allekirjoittamaton pitkä. Ja muut ovat ainutlaatuisia Cythonille, kuten bint, Pythonin C-tason esitys Tosi / väärä arvot.

cdef ja cpdef toimintotyypit

cdef avainsana ilmaisee Cython- tai C-tyypin käytön. Sitä käytetään myös funktioiden määrittelemiseen paljon kuin Pythonissa.

Cythonissa Pythonin avulla kirjoitetut toiminnot def avainsana näkyvät muille Python-koodeille, mutta niistä veloitetaan suoritusrangaistus. Toiminnot, jotka käyttävät cdef avainsana näkyy vain muille Cython- tai C-koodeille, mutta se suoritetaan paljon nopeammin. Jos sinulla on toimintoja, joita kutsutaan vain sisäisesti Cython-moduulista, käytä cdef.

Kolmas avainsana, cpdef, tarjoaa yhteensopivuuden sekä Python-koodin että C-koodin kanssa siten, että C-koodi pääsee ilmoitettuun toimintoon täydellä nopeudella. Tämä mukavuus maksaa kuitenkin:cpdef funktiot tuottavat enemmän koodia ja niillä on hieman enemmän puhelun yleiskuluja kuin cdef.

Muut Cython-avainsanat

Muut Cythonin avainsanat hallitsevat ohjelmavirran ja käyttäytymisen näkökohtia, jotka eivät ole käytettävissä Pythonissa:

  • gil ja nogil. Nämä ovat kontekstinhallintaohjelmia, joita käytetään määrittämään koodiosat, jotka edellyttävät (gil kanssa:) tai eivät vaadi (nogililla:) Python's Global Interpreter Lock tai GIL. C-koodi, joka ei soita Python-sovellusliittymää, voi toimia nopeammin a: ssa nogil esto, varsinkin jos se suorittaa pitkäaikaisen toiminnan, kuten lukemisen verkkoyhteydestä.
  • cimportTämä ohjaa Cythonin tuomaan C-tietotyypit, toiminnot, muuttujat ja laajennustyypit. Esimerkiksi CyPon-sovellukset, jotka käyttävät NumPyn alkuperäisiä C-moduuleja, käyttävät cimport päästäksesi käyttämään näitä toimintoja.
  • sisältää. Tämä sijoittaa yhden Cython-tiedoston lähdekoodin toiseen, samalla tavalla kuin C: ssä. Huomaa, että Cythonilla on kehittyneempi tapa jakaa ilmoituksia muiden Cython-tiedostojen välillä kuin vain sisältääs.
  • ctypedef. Käytetään viittaamaan ulkoisten C-otsikkotiedostojen tyyppimäärityksiin.
  • ulkoinen. Käytetään cdef viitata muissa moduuleissa oleviin C-funktioihin tai muuttujiin.
  • julkinen / api. Käytetään tekemään ilmoituksia Cython-moduuleissa, jotka näkyvät muille C-koodeille.
  • linjassa. Käytetään osoittamaan, että tietty funktio tulee olla viivoitettu tai sen koodi on asetettava kutsufunktion runkoon aina, kun sitä käytetään, nopeuden vuoksi. Esimerkiksi f funktio yllä olevassa koodiesimerkissä voisi olla koristeltu linjassa vähentää toimintakutsun yleiskustannuksia, koska sitä käytetään vain yhdessä paikassa. (Huomaa, että C-kääntäjä saattaa suorittaa oman rivinsä automaattisesti, mutta linjassa voit määrittää nimenomaisesti, pitäisikö jotain lisätä riviin.)

Kaikkia Cython-avainsanoja ei tarvitse tietää etukäteen. Cython-koodi kirjoitetaan yleensä asteittain - ensin kirjoitat kelvollisen Python-koodin ja lisäät sitten Cython-koristelun sen nopeuttamiseksi. Näin voit noutaa Cythonin laajennetun avainsanan syntaksin paloittain tarpeen mukaan.

Käännä Cython

Nyt kun meillä on jonkinlainen käsitys siitä, miltä yksinkertainen Cython-ohjelma näyttää ja miksi se näyttää tältä, käymme läpi vaiheet, jotka tarvitaan Cythonin kokoamiseksi toimivaksi binaariksi.

Toimivan Cython-ohjelman rakentamiseen tarvitaan kolme asiaa:

  1. Python-tulkki. Käytä uusinta versiota, jos voit.
  2. Cython-paketti. Voit lisätä Cythonin Pythoniin pip paketinhallinta: pip asenna cython
  3. C-kääntäjä.

Kohde # 3 voi olla hankala, jos käytät Microsoft Windowsia kehitysalustana. Toisin kuin Linux, Windowsissa ei ole C-kääntäjää vakiona. Korjaa ongelma tarttumalla kopioon Microsoft Visual Studio Community Editionista, joka sisältää Microsoftin C-kääntäjän eikä maksa mitään.

Huomaa, että tämän kirjoituksen jälkeen Cythonin uusin julkaisuversio on 0.29.16, mutta Cython 3.0: n beetaversio on käytettävissä. Jos käytät pip asenna cython, uusin ei-beetaversio asennetaan. Jos haluat kokeilla betaa, käytä pip install cython> = 3.0a1 asentaa Cython 3.0 -haaran uusin versio. Cythonin kehittäjät suosittelevat Cython 3.0 -haaran kokeilua aina kun mahdollista, koska joissakin tapauksissa se tuottaa huomattavasti nopeamman koodin.

Cython-ohjelmat käyttävät .pyx tiedostopääte. Luo uuteen hakemistoon tiedosto nimeltä numero.pyx joka sisältää yllä esitetyn Cython-koodiesimerkin (toinen koodinäyte kohdassa "A Cython-esimerkki") ja tiedoston nimeltä main.py joka sisältää seuraavan koodin:

numerosta import integrate_f

tulosta (integroi_f (1.0, 10.0, 2000))

Tämä on tavallinen Python-ohjelmisto, joka kutsuu integroida_f löytyy toimintonumero.pyx. Python-koodi “näkee” Cython-koodin vain yhtenä moduulina, joten sinun ei tarvitse tehdä mitään muuta kuin tuoda käännetty moduuli ja suorittaa sen toiminnot.

Lisää lopuksi tiedosto nimeltä setup.py seuraavalla koodilla:

from distutils.core tuontiasetukset distutilsista. laajennuksen tuonti laajennus Cythonista. Rakenna tuonti cythonize ext_modules = [Laajennus (r'num ', [r'num.pyx']),] setup (nimi = "num", ext_modules = cythonize (ext_modules),

)

setup.py Python käyttää normaalisti asennettavan moduulin asentamiseen, ja sitä voidaan käyttää myös ohjaamaan Python C-laajennusten kokoamiseen kyseiselle moduulille. Tässä käytämme setup.py kääntää Cython-koodi.

Jos olet Linux-käyttöjärjestelmässä ja sinulla on asennettuna C-kääntäjä (yleensä tapaus), voit kääntää .pyx tiedosto C: lle suorittamalla komento:

python setup.py build_ext --inplace

Jos käytät Microsoft Windowsia ja Microsoft Visual Studio 2017: ää tai uudempaa, sinun on varmistettava, että sinulla on uusin versio niistä asennustyökalut asennettu Pythoniin (versio 46.1.3 tämän kirjoituksen jälkeen), ennen kuin komento toimii. Tämä varmistaa, että Pythonin rakennustyökalut pystyvät tunnistamaan ja käyttämään asentamaasi Visual Studion versiota automaattisesti.

Jos kokoaminen onnistuu, sinun pitäisi nähdä uudet tiedostot hakemistossa: numero (Cythonin luoman C-tiedoston) ja tiedoston, jossa on joko a .o laajennus (Linuxissa) tai a .pyd laajennus (Windows). Se on binääri, johon C-tiedosto on koottu. Saatat myös nähdä a \rakentaa alihakemisto, joka sisältää rakennusprosessin artefaktit.

Juosta python main.py, ja sinun pitäisi nähdä vastauksena jotain seuraavanlaista:

283.297530375

Se on käännetyn integraalitoiminnon lähtö, johon puhdas Python-koodimme on vedonnut. Yritä pelata parametreille, jotka on siirretty funktiolle main.py nähdäksesi kuinka tulos muuttuu.

Huomaa, että aina, kun teet muutoksia .pyx tiedosto, sinun on käännettävä se uudelleen. (Kaikki muutokset, jotka teet tavalliseen Python-koodiin, tulevat voimaan välittömästi.)

Tuloksena olevalla käännetyllä tiedostolla ei ole riippuvuuksia lukuun ottamatta Pythonin versiota, johon se on käännetty, ja se voidaan niputtaa binaaripyörään. Huomaa, että jos viitat koodissasi muihin kirjastoihin, kuten NumPy (katso alla), sinun on annettava ne osana sovelluksen vaatimuksia.

Kuinka käyttää Cythonia

Nyt kun tiedät kuinka "Cythonize" koodinpala, seuraava askel on määrittää, kuinka Python-sovelluksesi voi hyötyä Cythonista. Missä sitä tarkalleen tulisi käyttää?

Saat parhaat tulokset optimoimalla tällaiset Python-toiminnot Cythonilla:

  1. Toiminnot, jotka toimivat tiukoissa silmukoissa tai vaativat pitkiä käsittelyaikoja yhdessä koodin "hot spotissa".
  2. Toiminnot, jotka suorittavat numeerisia manipulaatioita.
  3. Toiminnot, jotka toimivat sellaisten objektien kanssa, jotka voidaan esittää puhtaassa C-muodossa, kuten perusnumeeriset tyypit, taulukot tai rakenteet, eikä Python-objektityypit, kuten luettelot, sanakirjat tai joukot.

Python on perinteisesti ollut vähemmän tehokas silmukoissa ja numeerisissa käsittelyissä kuin muut tulkitsemattomat kielet. Mitä enemmän koristat koodiasi osoittaaksesi, että sen tulisi käyttää perusnumeerisia tyyppejä, jotka voidaan muuttaa C: ksi, sitä nopeammin se suorittaa numeromurskauksen.

Python-objektityyppien käyttö Cythonissa ei sinänsä ole ongelma. Python-objekteja käyttävät Cython-toiminnot kääntyvät edelleen, ja Python-objektit voivat olla suositeltavia, kun suorituskyky ei ole tärkein asia. Mutta mitä tahansa Python-objekteja käyttävää koodia rajoittaa Python-ajonaikainen suorituskyky, sillä Cython luo koodin suoraan Pythonin sovellusliittymiin ja ABI: hin.

Toinen arvoinen Cython-optimoinnin kohde on Python-koodi, joka on vuorovaikutuksessa suoraan C-kirjaston kanssa. Voit ohittaa Pythonin käärimiskoodin ja käyttöliittymän kirjastojen kanssa suoraan.

Cython kuitenkin tekeeei automaattisesti luoda oikeat puhelurajapinnat näille kirjastoille. Sinulla on oltava Cython, joka viittaa kirjaston otsikkotiedostojen funktion allekirjoituksiin a-muodossa cdef extern mistä vakuutus. Huomaa, että jos sinulla ei ole otsikkotiedostoja, Cython on anteeksiantavainen, jotta voit ilmoittaa ulkoisten toimintojen allekirjoitukset, jotka vastaavat alkuperäisiä otsikoita. Mutta käytä alkuperäisiä aina kun mahdollista olla turvallinen.

Yksi ulkoinen C-kirjasto, jota Cython voi käyttää heti pakkauksesta, on NumPy. Hyödynnä Cythonin nopeaa pääsyä NumPy-matriiseihin käyttämällä cimport numero (valinnaisesti kuten np pitää sen nimitila erillisenä) ja käytä sitten cdef käskyt ilmoittaakseen NumPy-muuttujat, kuten cdef np. haara tai np. siisti.

Cython-profilointi

Ensimmäinen askel sovelluksen suorituskyvyn parantamiseksi on profiloida se - luoda yksityiskohtainen raportti siitä, mihin aika kulutetaan suorituksen aikana. Python tarjoaa sisäänrakennetut mekanismit koodiprofiilien luomiseen. Cython ei vain tartu näihin mekanismeihin, vaan sillä on omat profilointityökalut.

Pythonin oma profiloija, cProfiili, luo raportit, jotka osoittavat, mitkä toiminnot vievät eniten aikaa tietyssä Python-ohjelmassa. Oletuksena Cython-koodi ei näy näissä raporteissa, mutta voit ottaa profiloinnin käyttöön Cython-koodilla lisäämällä kääntäjädirektiivin .pyx tiedosto toiminnoilla, jotka haluat sisällyttää profilointiin:

# cython: profile = True

Voit myös ottaa rivi riviltä jäljityksen Cythonin luomaan C-koodiin, mutta tämä aiheuttaa paljon yleiskustannuksia, joten se on oletusarvoisesti pois käytöstä.

Huomaa, että profilointi asettaa suorituskykyosuman, joten muista vaihtaa profilointi tuotantoon lähetettävälle koodille.

Cython voi myös luoda koodiraportteja, jotka osoittavat, kuinka paljon annettua .pyx tiedosto muunnetaan C: ksi, ja kuinka suuri osa siitä on jäljellä Python-koodina. Jos haluat nähdä tämän toiminnassa, muokkaa setup.py tiedosto esimerkissämme ja lisää seuraavat kaksi riviä yläosaan:

tuo Cython.Compiler.Options

Cython.Compiler.Options.annotate = Tosi

(Vaihtoehtoisesti voit käyttää huomautuksia setup.py-ohjelmassa, mutta yllä olevaa menetelmää on usein helpompi käyttää.)

Poista .c tiedostot, jotka on luotu projektissa, ja suorita setup.py käsikirjoitus kokoamaan kaikki uudelleen. Kun olet valmis, sinun pitäisi nähdä HTML-tiedosto samassa hakemistossa, joka jakaa .pyx-tiedostosi nimen - tässä tapauksessanumero.html. Avaa HTML-tiedosto ja näet koodin osat, jotka ovat edelleen riippuvaisia ​​Pythonista, korostettuna keltaisella. Voit napsauttaa keltaisia ​​alueita nähdäksesi taustalla olevan Cythonin luoman C-koodin.