Programování

Výukový program pro Cython: Jak zrychlit Python

Python je výkonný programovací jazyk, který se snadno naučí a snadno se s ním pracuje, ale jeho spuštění není vždy nejrychlejší - zejména pokud se zabýváte matematikou nebo statistikami. Knihovny třetích stran, jako je NumPy, které obklopují knihovny C, mohou výrazně zlepšit výkon některých operací, ale někdy potřebujete pouze surovou rychlost a sílu C přímo v Pythonu.

Cython byl vyvinut s cílem usnadnit psaní rozšíření C pro Python a umožnit transformaci stávajícího kódu Pythonu na C. A co víc, Cython umožňuje dodávku optimalizovaného kódu s aplikací Python bez externích závislostí.

V tomto kurzu projdeme kroky potřebné k transformaci existujícího kódu Pythonu na Cython a jeho použití v produkční aplikaci.

Související video: Použití Cythonu k urychlení Pythonu

Příklad Cythonu

Začněme jednoduchým příkladem převzatým z dokumentace Cythonu, ne příliš efektivní implementací integrální funkce:

def f (x):

návrat x ** 2-x

def integrate_f (a, b, N):

s = 0

dx = (b-a) / N

pro i v rozsahu (N):

s + = f (a + i * dx)

vrátit s * dx

Kód je snadno čitelný a srozumitelný, ale běží pomalu. Je to proto, že Python musí neustále převádět tam a zpět mezi svými vlastními typy objektů a surovými číselnými typy stroje.

Nyní zvažte verzi stejného kódu pro Cython, s podtrženými doplňky Cython:

 cdef f (double x):

návrat x ** 2-x

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

cdef int i

cdef double s, x, dx

s = 0

dx = (b-a) / N

pro i v rozsahu (N):

s + = f (a + i * dx)

vrátit s * dx

Tyto doplňky nám umožňují explicitně deklarovat typy proměnných v celém kódu, aby překladač Cython mohl tyto „zdobené“ doplňky přeložit do C.

Související video: Jak Python usnadňuje programování

Perfektní pro IT, Python zjednodušuje mnoho druhů práce, od automatizace systému až po práci v nejmodernějších oborech, jako je strojové učení.

Cythonova syntaxe

Klíčová slova použitá k dekoraci kódu Cython se nenacházejí v konvenční syntaxi Pythonu. Byly vyvinuty speciálně pro Cython, takže žádný z nich zdobený kód nebude fungovat jako běžný program v Pythonu.

Toto jsou nejběžnější prvky Cythonovy syntaxe:

Variabilní typy

Některé z typů proměnných používaných v Cythonu jsou ozvěnami vlastních typů Pythonu, napříkladint, plovák, a dlouho. Další typy proměnných Cython se také nacházejí v jazyce C, jako char nebo struktur, stejně jako prohlášení jako bez znaménka dlouho. A další jsou pro Cython jedinečné bint, reprezentace Pythonu na úrovni C. Pravda / nepravda hodnoty.

The cdef a cpdef typy funkcí

The cdef klíčové slovo označuje použití typu Cython nebo C. Používá se také k definování funkcí stejně jako v Pythonu.

Funkce napsané v Cythonu pomocí Pythonu def klíčové slovo jsou viditelné pro ostatní kód Pythonu, ale způsobují výkonnostní trest. Funkce, které používají cdef klíčové slovo jsou viditelné pouze pro ostatní Cython nebo C kód, ale provádějí se mnohem rychleji. Pokud máte funkce, které jsou volány pouze interně z modulu Cython, použijte cdef.

Třetí klíčové slovo, cpdef, poskytuje kompatibilitu jak s kódem Pythonu, tak s kódem C, a to tak, že kód C může přistupovat k deklarované funkci při plné rychlosti. Tato výhoda však stojí za cenu:cpdef funkce generují více kódu a mají o něco větší režii volání než cdef.

Další klíčová slova Cython

Další klíčová slova v Cythonu poskytují kontrolu nad aspekty toku programu a chování, které nejsou v Pythonu k dispozici:

  • Gil a nogil. Jedná se o správce kontextu, kteří se používají k vymezení částí kódu, které vyžadují (s Gilem:) nebo nevyžadují (s nogilem:) Globální tlumočnický zámek Pythonu nebo GIL. C kód, který neprovádí volání na Python API, může běžet rychleji v nogil blok, zejména pokud provádí dlouhodobou operaci, jako je čtení ze síťového připojení.
  • cimportTo nasměruje Cython k importu datových typů C, funkcí, proměnných a typů rozšíření. Používají například aplikace Cython, které používají nativní C moduly NumPy cimport získat přístup k těmto funkcím.
  • zahrnout. Tím se zdrojový kód jednoho souboru Cython umístí dovnitř jiného, ​​podobně jako v C. Všimněte si, že Cython má sofistikovanější způsob sdílení deklarací mezi soubory Cython kromě jiného zahrnouts.
  • ctypedef. Používá se k označení definic typů v externích souborech záhlaví C.
  • externí. Používá se s cdef odkazovat na C funkce nebo proměnné nalezené v jiných modulech.
  • public / api. Slouží k vytváření deklarací v modulech Cython, které budou viditelné pro další kód C.
  • v souladu. Používá se k označení dané funkce by měla být z důvodu rychlosti inline nebo mít její kód umístěn v těle volající funkce, kdykoli je použita. Například F funkce ve výše uvedeném příkladu kódu může být zdobena v souladu snížit jeho režii volání funkce, protože se používá pouze na jednom místě. (Všimněte si, že kompilátor C může provádět vlastní vkládání automaticky, ale v souladu vám umožní výslovně určit, zda má být něco vloženo.)

Není nutné znát všechna klíčová slova Cython předem. Cythonský kód má tendenci se psát postupně - nejprve napíšete platný Pythonův kód, poté přidáte Cythonovu dekoraci, abyste to urychlili. Můžete si tedy po částech vyzvednout rozšířenou syntaxi klíčových slov Cython, jak potřebujete.

Zkompilujte Cython

Nyní, když máme nějakou představu o tom, jak vypadá jednoduchý program Cython a proč vypadá tak, jak vypadá, pojďme si projít kroky potřebné ke kompilaci Cythonu do fungujícího binárního souboru.

K vytvoření funkčního programu Cython budeme potřebovat tři věci:

  1. Tlumočník Pythonu. Pokud je to možné, použijte nejnovější verzi.
  2. Balíček Cython. Cython můžete přidat do Pythonu pomocí pip správce balíčků: pip install cython
  3. Překladač C.

Položka č. 3 může být složitá, pokud jako vývojovou platformu používáte Microsoft Windows. Na rozdíl od Linuxu Windows nepřichází s kompilátorem C jako standardní komponentou. Chcete-li to vyřešit, pořiďte si kopii Microsoft Visual Studio Community Edition, která obsahuje kompilátor C společnosti Microsoft a nic nestojí.

Všimněte si, že od tohoto psaní je nejnovější verze Cythonu 0.29.16, ale k dispozici je beta verze Cython 3.0. Pokud používáte pip install cython, nainstaluje se nejnovější verze než beta. Pokud si chcete vyzkoušet beta verzi, použijte pip install cython> = 3.0a1 nainstalovat nejnovější vydání větve Cython 3.0. Vývojáři společnosti Cython doporučují vyzkoušet větev Cython 3.0, kdykoli je to možné, protože v některých případech generuje výrazně rychlejší kód.

Programy Cython používají .monstrance přípona souboru. V novém adresáři vytvořte soubor s názvem num.pyx , který obsahuje výše uvedený příklad kódu Cython (druhý ukázkový kód v části „Příklad Cython“) a soubor s názvem main.py který obsahuje následující kód:

z num import integrate_f

tisk (integrate_f (1.0, 10.0, 2000))

Toto je běžný program v Pythonu, který bude volat integrovat_f funkce nalezena vnum.pyx. Kód Pythonu „vidí“ kód Cythonu jen jako další modul, takže nemusíte dělat nic zvláštního, než importovat kompilovaný modul a spouštět jeho funkce.

Nakonec přidejte soubor s názvem setup.py s následujícím kódem:

z distutils.core import nastavení z distutils.extension import Rozšíření z Cython.Build import cythonize ext_modules = [Extension (r'num ', [r'num.pyx']),] setup (name = "num", ext_modules = cythonize (ext_modules),

)

setup.py je běžně používán Pythonem k instalaci modulu, ke kterému je přidružen, a lze jej také použít k nasměrování Pythonu ke kompilaci rozšíření C pro tento modul. Zde používáme setup.py sestavit Cythonův kód.

Pokud používáte Linux a máte nainstalovaný kompilátor C (obvykle případ), můžete kompilovat .monstrance soubor do C spuštěním příkazu:

python setup.py build_ext - místo

Pokud používáte Microsoft Windows a Microsoft Visual Studio 2017 nebo lepší, budete si muset ověřit, zda máte nejnovější verzi instalační nástroje nainstalován v Pythonu (verze 46.1.3 od tohoto psaní), než bude tento příkaz fungovat. Tím je zajištěno, že nástroje pro sestavení Pythonu budou schopny automaticky detekovat a používat verzi sady Visual Studio, kterou jste nainstalovali.

Pokud je kompilace úspěšná, měli byste vidět, že se v adresáři objeví nové soubory: num.c (soubor C generovaný společností Cython) a soubor s a rozšíření (na Linuxu) nebo a .pyd rozšíření (ve Windows). To je binární soubor, do kterého byl kompilován soubor C. Můžete také vidět a \stavět podadresář, který obsahuje artefakty z procesu sestavení.

Běh python main.py, a měli byste vidět něco jako následující vrácené jako odpověď:

283.297530375

To je výstup z kompilované integrální funkce vyvolané naším čistým kódem Pythonu. Zkuste hrát s parametry předanými funkci v main.py vidět, jak se výstup mění.

Pamatujte, že kdykoli provedete změny v souboru .monstrance souboru, budete jej muset překompilovat. (Jakékoli změny, které provedete v konvenčním kódu Pythonu, se projeví okamžitě.)

Výsledný kompilovaný soubor nemá žádné závislosti kromě verze Pythonu, pro kterou byl zkompilován, a může být svázán do binárního kola. Všimněte si, že pokud ve svém kódu odkazujete na jiné knihovny, například NumPy (viz níže), budete je muset poskytnout jako součást požadavků aplikace.

Jak používat Cython

Nyní, když víte, jak „cythonizovat“ část kódu, je dalším krokem určit, jak může vaše aplikace v Pythonu těžit z Cythonu. Kde přesně byste to měli použít?

Pro dosažení nejlepších výsledků použijte Cython k optimalizaci těchto druhů funkcí Pythonu:

  1. Funkce, které běží v těsných smyčkách nebo vyžadují dlouhé množství času zpracování v jediném „horkém místě“ kódu.
  2. Funkce, které provádějí numerické manipulace.
  3. Funkce, které pracují s objekty, které lze reprezentovat v čistém C, jako jsou základní číselné typy, pole nebo struktury, spíše než typy objektů Pythonu, jako jsou seznamy, slovníky nebo n-tice.

Python byl tradičně méně účinný ve smyčkách a numerických manipulacích než jiné, neinterpretované jazyky. Čím více svůj kód vyzdobíte, abyste naznačili, že by měl používat základní číselné typy, které lze převést na C, tím rychleji to udělá číslo.

Použití typů objektů Python v Cythonu není samo o sobě problém. Funkce Cythonu, které používají objekty Pythonu, se budou i nadále kompilovat a objekty Pythonu mohou být vhodnější, když výkon není nejdůležitějším hlediskem. Ale jakýkoli kód, který využívá objekty Pythonu, bude omezen výkonem běhového prostředí Pythonu, protože Cython vygeneruje kód, který přímo adresuje API a ABI Pythonu.

Dalším hodným cílem optimalizace Cythonu je kód Pythonu, který interaguje přímo s knihovnou C. Můžete přímo přeskočit „obalový“ kód Pythonu a rozhraní s knihovnami.

Cython to však děláne automaticky generuje správná rozhraní volání pro tyto knihovny. Budete muset nechat Cython odkazovat na podpisy funkcí v souborech záhlaví knihovny, a cdef mimo prohlášení. Všimněte si, že pokud nemáte soubory záhlaví, Cython dostatečně odpouští, aby vám umožnil deklarovat podpisy externích funkcí, které se blíží původním záhlaví. Abyste však byli v bezpečí, používejte originály, kdykoli je to možné.

Jedna externí knihovna C, kterou může Cython používat ihned po vybalení z krabice, je NumPy. Chcete-li využít výhod rychlého přístupu Cythonu k polím NumPy, použijte cimport numpy (volitelně s jako np aby byl jeho jmenný prostor odlišný) a poté použijte cdef příkazy k deklaraci proměnných NumPy, například cdef np.array nebo np.ndarray.

Cythonské profilování

Prvním krokem ke zlepšení výkonu aplikace je její profilování - vygenerování podrobné zprávy o tom, kde se čas během provádění vynakládá. Python poskytuje vestavěné mechanismy pro generování kódových profilů. Cython se nejen zapojuje do těchto mechanismů, ale má vlastní profilovací nástroje.

Pythonův vlastní profiler, cProfil, generuje zprávy, které ukazují, které funkce zabírají v daném programu v Pythonu nejvíce času. Ve výchozím nastavení se kód Cythonu v těchto přehledech nezobrazuje, ale můžete povolit profilování kódu Cython vložením direktivy kompilátoru v horní části .monstrance soubor s funkcemi, které chcete zahrnout do profilování:

# cython: profile = True

Můžete také povolit trasování řádek po řádku v kódu C generovaném Cythonem, ale to ukládá spoustu režijních nákladů, a proto je ve výchozím nastavení vypnuto.

Všimněte si, že profilování ukládá požadavek na výkon, takže nezapomeňte profilování vypnout pro kód, který se dodává do výroby.

Cython může také generovat zprávy o kódu, které udávají, kolik z daného .monstrance soubor se převádí na C a kolik z toho zbývá v Pythonu. Chcete-li to vidět v akci, upravte setup.py soubor v našem příkladu a přidejte následující dva řádky nahoře:

importovat možnosti Cython.Compiler.Options

Cython.Compiler.Options.annotate = True

(Alternativně můžete použít direktivu v setup.py k povolení anotací, ale s výše uvedenou metodou je často snazší pracovat.)

Odstranit .C soubory generované v projektu a znovu spusťte soubor setup.py skript vše překompilovat. Po dokončení byste měli vidět soubor HTML ve stejném adresáři, který sdílí název vašeho souboru .pyx - v tomto případěnum.html. Otevřete soubor HTML a uvidíte části kódu, které jsou stále závislé na Pythonu, zvýrazněny žlutě. Kliknutím na žluté oblasti zobrazíte podkladový C kód vygenerovaný Cythonem.

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