Programovanie

Výukový program pre Cython: Ako zrýchliť Python

Python je výkonný programovací jazyk, ktorý sa dá ľahko naučiť a ľahko sa s ním pracuje, ale jeho spustenie nie je vždy najrýchlejšie - najmä ak sa zaoberáte matematikou alebo štatistikou. Knižnice tretích strán, ako napríklad NumPy, ktoré zabaľujú knižnice C, môžu výrazne zlepšiť výkon niektorých operácií, niekedy však potrebujete iba surovú rýchlosť a výkon C priamo v Pythone.

Cython bol vyvinutý s cieľom uľahčiť písanie rozšírení C pre Python a umožniť transformáciu existujúceho kódu Pythonu na C. A čo viac, Cython umožňuje dodanie optimalizovaného kódu spolu s aplikáciou Python bez externých závislostí.

V tomto výučbe sa oboznámime s krokmi potrebnými na transformáciu existujúceho kódu Python na Cython a na jeho použitie v produkčnej aplikácii.

Súvisiace video: Používanie Cythonu na zrýchlenie Pythonu

Príklad Cython

Začnime jednoduchým príkladom prevzatým z dokumentácie spoločnosti Cython, nie veľmi účinnou implementáciou integrálnej funkcie:

def f (x):

návrat x ** 2-x

def integrate_f (a, b, N):

s = 0

dx = (b-a) / N

pre i v rozsahu (N):

s + = f (a + i * dx)

návrat s * dx

Kód je ľahko čitateľný a zrozumiteľný, ale beží pomaly. Je to preto, že Python musí neustále prevádzať tam a späť medzi svojimi vlastnými typmi objektov a surovými číselnými typmi stroja.

Teraz zvážte verziu rovnakého kódu pre Cython, ktorej podčiarknuté doplnky sú:

 cdef f (dvojité x):

návrat x ** 2-x

def integrate_f (dvojité a, dvojité b, int N):

cdef int i

cdef double s, x, dx

s = 0

dx = (b-a) / N

pre i v rozsahu (N):

s + = f (a + i * dx)

návrat s * dx

Tieto dodatky nám umožňujú explicitne deklarovať typy premenných v celom kóde, aby kompilátor Cython mohol tieto „zdobené“ doplnky preložiť do jazyka C.

Súvisiace video: Ako Python uľahčuje programovanie

Python, perfektný pre IT, zjednodušuje mnoho druhov práce, od automatizácie systému až po prácu v špičkových oblastiach, ako je strojové učenie.

Cythonova syntax

Kľúčové slová použité na ozdobenie kódu Cython sa nenachádzajú v konvenčnej syntaxe Pythonu. Boli vyvinuté špeciálne pre Cython, takže žiadny nimi zdobený kód nebude fungovať ako konvenčný program v Pythone.

Toto sú najbežnejšie prvky Cythonovej syntaxe:

Variabilné typy

Niektoré z typov premenných používaných v Cythone sú ozvenami vlastných typov Pythonu, ako naprint, plaváka dlho. Ostatné typy premenných Cython sa tiež nachádzajú v jazyku C ako char alebo štruktúr, ako sú aj vyhlásenia podobné nepodpísaný dlho. A ďalšie sú napríklad pre Cython jedinečné bint, reprezentácia Pythonu na úrovni C. Pravda lož hodnoty.

The cdef a cpdef typy funkcií

The cdef kľúčové slovo označuje použitie typu Cython alebo C. Používa sa tiež na definovanie funkcií podobne ako v Pythone.

Funkcie napísané v Cythone pomocou jazyka Python def kľúčové slovo sú viditeľné pre iný kód Pythonu, ale hrozí za ne výkonnostný trest. Funkcie, ktoré používajú cdef kľúčové slovo sú viditeľné iba pre iný Cython alebo C kód, ale vykonávajú sa oveľa rýchlejšie. Ak máte funkcie, ktoré sa volajú iba interne z modulu Cython, použite cdef.

Tretie kľúčové slovo, cpdef, poskytuje kompatibilitu s kódom Python aj s kódom C takým spôsobom, že kód C má prístup k deklarovanej funkcii pri plnej rýchlosti. Táto vymoženosť je spoplatnená, avšak:cpdef funkcie generujú viac kódu a majú o niečo väčšiu réžiu hovoru ako cdef.

Ostatné kľúčové slová v jazyku Cython

Ostatné kľúčové slová v Cythone poskytujú kontrolu nad aspektmi toku programu a správaním, ktoré nie sú k dispozícii v Pythone:

  • Gil a nogil. Toto sú správcovia kontextu, ktorí sa používajú na vymedzenie častí kódu, ktoré vyžadujú (s Gil:) alebo nevyžadujú (s nogilom:) Globálny tlmočnícky zámok Pythonu alebo GIL. C kód, ktorý neuskutočňuje žiadne hovory na Python API, môže bežať rýchlejšie v a nogil blok, najmä ak vykonáva dlhodobú operáciu, napríklad čítanie zo sieťového pripojenia.
  • cimportToto nasmeruje Cython na import dátových typov C, funkcií, premenných a typov rozšírení. Používajú napríklad aplikácie Cython, ktoré používajú natívne moduly C spoločnosti NumPy cimport získať prístup k týmto funkciám.
  • zahrnúť. Toto umiestni zdrojový kód jedného súboru Cython do druhého, a to rovnakým spôsobom ako v jazyku C. Upozorňujeme, že Cython má sofistikovanejší spôsob zdieľania vyhlásení medzi súbormi Cython okrem iného zahrnúťs.
  • ctypedef. Používa sa na označenie definícií typov v externých súboroch hlavičky C.
  • externý. Používa sa s cdef odkazovať na C funkcie alebo premenné nájdené v iných moduloch.
  • public / api. Používa sa na vytváranie vyhlásení v moduloch Cython, ktoré budú viditeľné pre ďalší kód C.
  • v rade. Používa sa na označenie, že daná funkcia by mala byť kvôli rýchlosti vložená do riadku alebo by mal byť jej kód umiestnený v tele volajúcej funkcie, kedykoľvek je použitá. Napríklad f funkcia vo vyššie uvedenom príklade kódu môže byť zdobená v rade znížiť svoju réžiu volania funkcie, pretože sa používa iba na jednom mieste. (Upozorňujeme, že kompilátor C môže vykonávať svoje vlastné vloženie automaticky, ale v rade vám umožní výslovne určiť, či má byť niečo podčiarknuté.)

Nie je potrebné poznať všetky kľúčové slová Cython vopred. Kód v jazyku Cython má tendenciu sa písať prírastkovo - najskôr napíšete platný kód v jazyku Python, potom na urýchlenie pridáte dekoráciu v jazyku Cython. Takto si môžete po častiach vyzdvihnúť rozšírenú syntaxu kľúčových slov spoločnosti Cython.

Zostavte Cython

Teraz, keď máme určitú predstavu o tom, ako vyzerá jednoduchý program Cython a prečo vyzerá tak, ako vyzerá, poďme si prejsť kroky potrebné na kompiláciu Cythonu do fungujúceho binárneho súboru.

Na zostavenie funkčného programu Cython budeme potrebovať tri veci:

  1. Tlmočník jazyka Python. Ak je to možné, použite najnovšiu verziu.
  2. Balík Cython. Cython do Pythonu môžete pridať pomocou pip správca balíkov: pip nainštalovať cython
  3. Kompilátor C.

Položka č. 3 môže byť zložitá, ak ako vývojovú platformu používate Microsoft Windows. Na rozdiel od Linuxu Windows neprichádza s kompilátorom C ako štandardnou súčasťou. Ak to chcete vyriešiť, vezmite si kópiu Microsoft Visual Studio Community Edition, ktorá obsahuje kompilátor C spoločnosti Microsoft a nič to nestojí.

Upozorňujeme, že od tohto písania je najnovšia vydaná verzia Cythonu 0.29.16, ale k dispozícii je beta verzia Cython 3.0. Ak používate pip nainštalovať cython, nainštaluje sa najaktuálnejšia verzia než beta. Ak si chcete vyskúšať beta verziu, použite pip install cython> = 3.0a1 nainštalovať najnovšie vydanie pobočky Cython 3.0. Vývojári spoločnosti Cython odporúčajú vyskúšať vetvu Cython 3.0, kedykoľvek je to možné, pretože v niektorých prípadoch generuje podstatne rýchlejší kód.

Programy Cython používajú .pyx rozšírenie súboru. V novom adresári vytvorte súbor s názvom num.pyx , ktorý obsahuje vyššie uvedený príklad kódu Cython (druhá ukážka kódu v časti „Príklad Cython“) a súbor s názvom main.py ktorý obsahuje nasledujúci kód:

od num import integrate_f

tlač (integrate_f (1.0, 10.0, 2000))

Toto je bežný program v Pythone, ktorý bude volať integrovať_f funkcia nájdená vnum.pyx. Kód Pythonu „vidí“ kód Cythonu iba ako ďalší modul, takže nemusíte robiť nič iné, než importovať kompilovaný modul a spúšťať jeho funkcie.

Nakoniec pridajte súbor s názvom setup.py s nasledujúcim kódom:

z distutils.core import nastavenia z distutils.extension import Extension z Cython.Build import cythonize ext_modules = [Extension (r'num ', [r'num.pyx']),] setup (name = "num", ext_modules = cythonize (ext_modules),

)

setup.py sa zvyčajne používa v Pythone na inštaláciu modulu, s ktorým je spojený, a môže sa tiež použiť na nasmerovanie Pythonu na kompiláciu rozšírení C pre tento modul. Tu používame setup.py na zostavenie kódu Cython.

Ak používate systém Linux a máte nainštalovaný kompilátor C (zvyčajne je to tak), môžete kompilovať súbor .pyx súbor do C spustením príkazu:

python setup.py build_ext --inplace

Ak používate Microsoft Windows a Microsoft Visual Studio 2017 alebo novší, budete si musieť overiť, či máte najnovšiu verziu servera setuptools nainštalovaný v Pythone (od tohto písania verzia 46.1.3) skôr, ako bude tento príkaz fungovať. To zaisťuje, že nástroje na zostavenie Pythonu budú schopné automaticky detekovať a používať verziu Visual Studio, ktorú ste nainštalovali.

Ak je kompilácia úspešná, mali by ste v adresári vidieť nové súbory: num.c (súbor C vygenerovaný spoločnosťou Cython) a súbor s a .o rozšírenie (na Linuxe) alebo a .pyd rozšírenie (vo Windows). To je binárny súbor, do ktorého bol kompilovaný súbor C. Môžete tiež vidieť a \ stavať podadresár, ktorý obsahuje artefakty z procesu zostavovania.

Bež python main.py, a mali by ste vidieť niečo ako nasledujúci vrátený ako odpoveď:

283.297530375

Toto je výstup z kompilovanej integrálnej funkcie, ako ju vyvolal náš čistý kód v jazyku Python. Skúste sa pohrať s parametrami odovzdanými funkcii v main.py aby sme videli, ako sa výstup mení.

Upozorňujeme, že kedykoľvek urobíte zmeny v dokumente .pyx súboru, budete ho musieť prekompilovať. (Všetky zmeny, ktoré vykonáte v konvenčnom kóde Pythonu, sa prejavia okamžite.)

Výsledný skompilovaný súbor nemá žiadne závislosti okrem verzie Pythonu, pre ktorú bol kompilovaný, a preto ho možno zoskupiť do binárneho kolieska. Upozorňujeme, že ak vo svojom kóde odkazujete na iné knižnice, napríklad NumPy (pozri nižšie), budete ich musieť uviesť ako súčasť požiadaviek aplikácie.

Ako používať Cython

Teraz, keď viete, ako „cythonizovať“ časť kódu, je ďalším krokom zistiť, ako môže vaša aplikácia v jazyku Python ťažiť z Cythonu. Kde konkrétne by ste ho mali použiť?

Najlepšie výsledky dosiahnete pomocou Cythonu na optimalizáciu týchto druhov funkcií Pythonu:

  1. Funkcie, ktoré bežia v obmedzených cykloch alebo vyžadujú veľké množstvo času na spracovanie v jednom „horúcom mieste“ kódu.
  2. Funkcie, ktoré vykonávajú numerické manipulácie.
  3. Funkcie, ktoré pracujú s objektmi, ktoré je možné reprezentovať v čistom C, napríklad základné číselné typy, polia alebo štruktúry, a nie s typmi objektov Python, ako sú zoznamy, slovníky alebo n-tice.

Python bol tradične pri cykloch a numerických manipuláciách menej efektívny ako iné jazyky, ktoré neboli interpretované. Čím viac kód zdobíte, aby ste naznačili, že by mal používať základné číselné typy, ktoré sa dajú premeniť na C, tým rýchlejšie to urobíte s číslami.

Používanie typov objektov Python v Cythone nie je samo o sebe problémom. Funkcie Cythonu, ktoré používajú objekty Pythonu, sa budú aj naďalej kompilovať a objekty Pythonu môžu byť vhodnejšie, keď výkon nie je najdôležitejšou otázkou. Ale akýkoľvek kód, ktorý využíva objekty Pythonu, bude obmedzený výkonom runtime Pythonu, pretože Cython vygeneruje kód na priamu adresu Pythonových API a ABI.

Ďalším hodnotným cieľom optimalizácie Cythonu je kód Pythonu, ktorý priamo interaguje s knižnicou C. Môžete priamo preskočiť „obalový“ kód Pythonu a rozhranie s knižnicami.

Cython to však robínie automaticky generuje správne rozhrania hovorov pre tieto knižnice. Budete musieť nechať Cythonom odkazovať na podpisy funkcií v hlavičkových súboroch knižnice, a cdef externe z vyhlásenie. Upozorňujeme, že ak nemáte hlavičkové súbory, Cython je dostatočne zhovievavý na to, aby vám umožnil deklarovať podpisy externých funkcií, ktoré sa približujú pôvodným hlavičkám. Ale vždy, keď je to možné, používajte originály, aby ste boli v bezpečí.

Jednou externou knižnicou C, ktorú môže Cython používať hneď po vybalení z krabice, je NumPy. Ak chcete využiť rýchly prístup Cythonu k poliam NumPy, použite cimport numpy (voliteľne s ako np aby bol jeho priestor názvov zreteľný), a potom použite cdef príkazy na deklaráciu premenných NumPy, ako napr cdef np.pole alebo np.ndarray.

Profilovanie v jazyku Cython

Prvým krokom k zlepšeniu výkonu aplikácie je jej profilovanie - vygenerovanie podrobnej správy o tom, kde sa čas strávi počas vykonávania. Python poskytuje zabudované mechanizmy na generovanie profilov kódu. Cython sa nielen zapojí do týchto mechanizmov, ale má aj svoje vlastné profilové nástroje.

Pythonov vlastný profilovač, cProfil, generuje správy, ktoré ukazujú, ktoré funkcie zaberajú v danom programe Python najviac času. Kód Cython sa predvolene v týchto prehľadoch nezobrazuje, ale môžete povoliť profilovanie na kóde Cython vložením smernice kompilátora do hornej časti .pyx súbor s funkciami, ktoré chcete zahrnúť do profilovania:

# cython: profile = True

Môžete tiež povoliť sledovanie riadkov po riadkoch v kóde C generovanom programom Cython, čo však vyžaduje veľa režijných nákladov, a preto je predvolene vypnuté.

Upozorňujeme, že profilovanie ukladá prístup k výkonu, takže pre kód, ktorý sa dodáva do výroby, profilovanie vypnite.

Cython môže tiež generovať správy o kóde, ktoré označujú, koľko z toho je dané .pyx súbor sa prevádza na C a koľko z neho zostáva v kóde Python. Ak to chcete vidieť v akcii, upravte setup.py súboru v našom príklade a hore pridajte nasledujúce dva riadky:

importovať možnosti Cython.Compiler.Options

Cython.Compiler.Options.annotate = Pravda

(Prípadne môžete použiť direktívu v setup.py na povolenie anotácií, ale s vyššie uvedenou metódou sa často pracuje ľahšie.)

Odstrániť .c súbory vygenerované v projekte a znovu spustite setup.py skript na prekompilovanie všetkého. Po dokončení by sa mal v rovnakom adresári zobraziť súbor HTML, ktorý zdieľa názov vášho súboru .pyx - v tomto prípadenum.html. Otvorte súbor HTML a uvidíte časti žltého kódu, ktoré stále závisia od jazyka Python. Kliknutím na žlté oblasti zobrazíte podkladový kód C vygenerovaný programom Cython.

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