Programování

Co je Cython? Python rychlostí C.

Python má pověst jednoho z nejpohodlnějších, bohatě vybavených a vyloženě užitečných programovacích jazyků. Rychlost provedení? Ne tak moc.

Zadejte Cython. Jazyk Cython je nadmnožinou Pythonu, který se kompiluje do jazyka C a přináší zvýšení výkonu, které se může pohybovat od několika procent do několika řádů, v závislosti na dané úloze. U prací, které jsou vázány nativními typy objektů Pythonu, nebudou zrychlení velká. Ale pro numerické operace nebo operace, které nezahrnují vlastní interní prvky Pythonu, mohou být zisky obrovské.

S Cythonem můžete obejít mnoho nativních omezení Pythonu nebo je zcela překonat - aniž byste se museli vzdát Pythonovy lehkosti a pohodlí. V tomto článku projdeme základní koncepty Cythonu a vytvoříme jednoduchou aplikaci v Pythonu, která pomocí Cythonu zrychlí jednu ze svých funkcí.

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

Kompilace Pythonu do C.

Kód v Pythonu umožňuje volání přímo do modulů C. Těmito moduly C mohou být buď obecné knihovny C, nebo knihovny vytvořené speciálně pro práci s Pythonem. Cython generuje druhý druh modulu: C knihovny, které komunikují s interními funkcemi Pythonu a které lze spojit se stávajícím kódem Pythonu.

Cythonský kód vypadá záměrně hodně jako Pythonův kód. Pokud přivedete kompilátor Cython do programu Python (Python 2.xa Python 3.x jsou oba podporovány), Cython to přijme tak, jak je, ale žádná z nativních akcelerací Cythonu se nedostane do hry. Pokud však vyzdobíte kód Pythonu anotacemi typů ve speciální syntaxi Cythonu, bude Cython schopen nahradit rychlé ekvivalenty C pomalými objekty Pythonu.

Všimněte si, že přístup společnosti Cython jepřírůstkové. To znamená, že vývojář může začít sexistující Aplikaci v Pythonu a zrychlete ji provedením přímých změn v kódu, místo přepisování celé aplikace od základu.

Tento přístup zapadá do povahy problémů s výkonem softwaru obecně. Ve většině programů je drtivá většina kódu náročného na procesor soustředěna do několika horkých míst - verze Paretova principu, známá také jako pravidlo „80/20“. Většina kódu v aplikaci Python tedy nemusí být optimalizována z hlediska výkonu, jen několik kritických částí. Tato horká místa můžete postupně přeložit do Cythonu, a tak získat výkonnostní zisky, které potřebujete, tam, kde to záleží nejvíce. Zbytek programu může zůstat v Pythonu pro pohodlí vývojářů.

Jak používat Cython

Zvažte následující kód převzatý z dokumentace společnosti Cython:

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

Toto je příklad hračky, ne příliš efektivní implementace integrální funkce. Jako čistý kód v Pythonu je to pomalé, protože Python musí konvertovat tam a zpět mezi strojově nativními numerickými typy a vlastními interními typy objektů.

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

 cdef double 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

Pokud explicitně deklarujeme typy proměnných, a to jak pro parametry funkce, tak pro proměnné použité v těle funkce (dvojnásobek, int, atd.), Cython toto vše přeloží do C. Můžeme také použít cdef klíčové slovo k definování funkcí, které jsou implementovány primárně v C pro další rychlost, i když tyto funkce lze volat pouze jinými funkcemi Cythonu a ne skripty Pythonu. (Ve výše uvedeném příkladu pouze integrovat_f lze volat jiným skriptem Pythonu.)

Všimněte si, jak málo je naše skutečnákód změnila. Všechno, co jsme udělali, je přidat deklarace typu do stávajícího kódu, abychom získali výrazné zvýšení výkonu.

Výhody Cythonu

Kromě možnosti urychlit kód, který jste již napsali, poskytuje Cython několik dalších výhod:

Práce s externími C knihovnami může být rychlejší

Balíčky Pythonu, jako je NumPy, zabalí knihovny C do rozhraní Pythonu, aby se s nimi snadno pracovalo. Jít sem a tam mezi Pythonem a C přes tyto obaly však může věci zpomalit. Cython vám umožňuje hovořit přímo se základními knihovnami bez Pythonu. (Podporovány jsou také knihovny C ++.)

Můžete použít správu paměti C i Python

Pokud používáte objekty Pythonu, jsou spravovány pamětí a shromažďovány stejně jako v běžném Pythonu. Ale pokud chcete vytvořit a spravovat své vlastní struktury na úrovni C a použít malloc/volný, uvolnit abyste s nimi mohli pracovat, můžete tak učinit. Nezapomeňte si po sobě uklidit.

Podle potřeby se můžete rozhodnout pro bezpečnost nebo rychlost

Cython automaticky provádí běhové kontroly běžných problémů, které se objevují v C, jako je přístup mimo pole v poli, pomocí dekorátorů a směrnic kompilátoru (např. @boundscheck (False)). V důsledku toho je C kód generovaný Cythonem ve výchozím nastavení mnohem bezpečnější než ručně C kód, i když potenciálně za cenu hrubého výkonu.

Pokud jste si jisti, že tyto kontroly za běhu nebudete potřebovat, můžete je deaktivovat pro další zvýšení rychlosti, a to buď v rámci celého modulu, nebo pouze u vybraných funkcí.

Cython také umožňuje nativní přístup ke strukturám Pythonu, které používají protokol vyrovnávací paměti pro přímý přístup k datům uloženým v paměti (bez mezilehlého kopírování). Zobrazení paměti Cython vám umožní pracovat s těmito strukturami vysokou rychlostí a s úrovní bezpečnosti odpovídající danému úkolu. Například surová data, která jsou základem řetězce Pythonu, lze číst tímto způsobem (rychle), aniž byste museli procházet běhovým modulem Pythonu (pomalu).

Kód Cython C může těžit z uvolnění GIL

Globální tlumočník Lock Pythonu (GIL) synchronizuje vlákna v tlumočníkovi, chrání přístup k objektům Pythonu a spravuje spory o zdroje. Ale GIL byl široce kritizován jako kámen úrazu výkonnějšího Pythonu, zejména na vícejádrových systémech.

Pokud máte část kódu, která nedává žádné odkazy na objekty Pythonu a provádí dlouhodobou operaci, můžete ji označit pomocís nogilem: směrnice umožňující jeho běh bez GIL. Tím se překladač Pythonu uvolní k provádění dalších věcí a umožní kódu Cythonu využívat více jader (s další prací).

Cython může používat syntaxi nápovědy typu Python

Python má syntaxi naznačující typ, která je používána hlavně lintery a kontrolami kódu, spíše než interpretem CPython. Cython má vlastní vlastní syntaxi pro dekoraci kódu, ale s nedávnými revizemi Cythonu můžete použít syntaxi naznačující typ Pythonu, abyste Cythonu poskytli také základní tipy.

Cython lze použít k zakrytí citlivého kódu Pythonu

Moduly v Pythonu lze triviálně snadno dekompilovat a zkontrolovat, ale kompilované binární soubory nejsou. Při distribuci aplikace v Pythonu koncovým uživatelům, pokud chcete chránit některé z jejích modulů před příležitostným snoopováním, můžete tak učinit jejich kompilací s Cythonem. Všimněte si, že se jedná o vedlejší účinek schopností Cythonu, ani jedna z jeho zamýšlených funkcí.

Cythonská omezení

Mějte na paměti, že Cython není kouzelná hůlka. Neznamená to, že automaticky změní každou instanci kódu kódu Pythonu na rychle rostoucí C kód. Chcete-li Cython využít co nejlépe, musíte jej používat moudře - a pochopit jeho omezení:

Malé zrychlení pro konvenční kód v Pythonu

Když Cython narazí na kód v Pythonu, nemůže se přeložit úplně do C, transformuje tento kód na řadu volání C do vnitřních prostor Pythonu. To znamená vyřazení interpreta Pythonu z prováděcí smyčky, což ve výchozím nastavení dává kódu mírné zrychlení o 15 až 20 procent. Toto je nejlepší scénář; v některých situacích nemusí dojít k žádnému zlepšení výkonu nebo dokonce ke snížení výkonu.

Malé zrychlení pro nativní datové struktury Pythonu

Python poskytuje spoustu datových struktur - řetězce, seznamy, n-tice, slovníky atd. Pro vývojáře jsou velmi výhodné a přicházejí s vlastní automatickou správou paměti. Ale jsou pomalejší než čisté C.

Cython vám umožní nadále používat všechny datové struktury Pythonu, i když bez velkého zrychlení. To je opět proto, že Cython jednoduše volá C API v běhovém prostředí Pythonu, které tyto objekty vytvářejí a manipulují s nimi. Datové struktury Pythonu se tedy chovají podobně jako Pythonův kód optimalizovaný pro Cython: Občas získáte podporu, ale jen málo. Pro dosažení nejlepších výsledků použijte proměnné a struktury C. Dobrou zprávou je, že Cython s nimi usnadňuje práci.

Cythonský kód běží nejrychleji, když je „čistý C“

Pokud máte funkci v C označenou cdef Klíčové slovo, se všemi jeho proměnnými a inline volání funkcí na jiné věci, které jsou čistě C, poběží tak rychle, jak to C půjde. Pokud ale tato funkce odkazuje na jakýkoli nativní kód Pythonu, jako je datová struktura Pythonu nebo volání interního rozhraní Python API, bude toto volání překážkou výkonu.

Naštěstí Cython poskytuje způsob, jak odhalit tato úzká místa: sestava zdrojového kódu, která na první pohled ukazuje, které části vaší aplikace Cython jsou čisté C a které části interagují s Pythonem. Čím lépe optimalizovaná aplikace, tím menší interakce s Pythonem.

Cython NumPy

Cython vylepšuje používání knihoven třetích stran založených na C, jako je NumPy. Protože se kód v Cythonu kompiluje do C, může s těmito knihovnami interagovat přímo a odstraňovat úzká místa Pythonu ze smyčky.

Ale zejména NumPy funguje dobře s Cythonem. Cython má nativní podporu pro konkrétní konstrukce v NumPy a poskytuje rychlý přístup k polím NumPy. A stejná známá syntaxe NumPy, kterou byste použili v běžném skriptu Pythonu, lze použít v Cythonu tak, jak jsou.

Pokud však chcete vytvořit nejbližší možné vazby mezi Cythonem a NumPy, musíte kód dále ozdobit vlastní syntaxí Cythonu. Thecimport Například příkaz umožňuje kódu Cython vidět konstrukce C-level v knihovnách v době kompilace pro nejrychlejší možné vazby.

Protože je NumPy tak široce používán, podporuje Cython NumPy „ihned po vybalení z krabice“. Pokud máte NumPy nainstalovaný, můžete pouze uvéstcimport numpy ve svém kódu, pak přidejte další dekoraci pro použití exponovaných funkcí.

Cythonské profilování a výkon

Nejlepší výkon získáte z jakéhokoli kódu tím, že jej profilováte a uvidíte na vlastní oči, kde jsou úzká místa. Cython poskytuje háčky pro modul cProfile v Pythonu, takže můžete použít vlastní profilovací nástroje Pythonu, jako je cProfile, abyste zjistili, jak funguje váš kód Cython.

Ve všech případech si pamatujte, že Cython není kouzelný - stále platí rozumné praktiky výkonu v reálném světě. Čím méně budete mezi Pythonem a Cythonem jezdit tam a zpět, tím rychleji bude vaše aplikace fungovat.

Například pokud máte kolekci objektů, které chcete v Cythonu zpracovat, nepererujte ji v Pythonu a v každém kroku vyvolávejte Cythonovu funkci. Složit celou sbírku do svého modulu Cython a iterujte tam. Tato technika se často používá v knihovnách, které spravují data, takže je to dobrý model emulace ve vašem vlastním kódu.

Používáme Python, protože poskytuje pohodlí programátora a umožňuje rychlý vývoj. Produktivita tohoto programátora někdy přichází za cenu výkonu. S Cythonem vám jen trochu úsilí navíc poskytne to nejlepší z obou světů.

Přečtěte si více o Pythonu

  • Co je Python? Výkonné a intuitivní programování
  • Co je PyPy? Rychlejší Python bez bolesti
  • Co je Cython? Python rychlostí C.
  • Výukový program pro Cython: Jak zrychlit Python
  • Jak chytře nainstalovat Python
  • Nejlepší nové funkce v Pythonu 3.8
  • Lepší správa projektů v Pythonu s poezií
  • Virtualenv a venv: Vysvětlení virtuálních prostředí Pythonu
  • Python virtualenv a venv dělá a nedělá
  • Vysvětlení vláken a podprocesů v Pythonu
  • Jak používat debugger Pythonu
  • Jak používat timeit k profilování kódu Pythonu
  • Jak používat cProfile k profilování kódu Pythonu
  • Začněte s asynchronizací v Pythonu
  • Jak používat asyncio v Pythonu
  • Jak převést Python na JavaScript (a zpět)
  • Python 2 EOL: Jak přežít konec Pythonu 2
  • 12 Pythons pro všechny programovací potřeby
  • 24 knihoven Pythonu pro každého vývojáře Pythonu
  • 7 sladkých IDE Pythonu, které vám možná chyběly
  • 3 hlavní nedostatky Pythonu - a jejich řešení
  • Porovnáno 13 webových rámců Pythonu
  • 4 testovací rámce Pythonu k rozdrcení vašich chyb
  • 6 skvělých nových funkcí Pythonu, které si nenechte ujít
  • 5 distribucí Pythonu pro zvládnutí strojového učení
  • 8 skvělých knihoven Pythonu pro zpracování přirozeného jazyka