Python

Z Denik

Verze z 2. 10. 2018, 06:10; Jst (diskuse | příspěvky)
(rozdíl) ← Starší verze | zobrazit aktuální verzi (rozdíl) | Novější verze → (rozdíl)
Přejít na: navigace, hledání

GraalVM umí spouštět různé jazyky, mimo jinými i Python. Proto jsem byl překvapený, že Pavel Tišňovský ve svých předchozích porovnáních různých implementací jazyka Python neuvedl i GraalPython (například při popisu RPythonu či Cythonu). Trochu uraženě jsem si tedy vyzkoušel, jak si s uvedeným Mandelbrot příkladem poradí náš Python. No a nakonec jsem byl vlastně rád, že to Pavel nevyzkoušel. Nejen, že to počítalo dlouho, ale hlavně počítalo úplně špatně. Výsledný obrázek vůbec nevypadal jako ty ostatní.

To však bylo na začátku srpna. Od té doby si s tím Petr Pišl hraje, udělal pár vylepšení a GraalVM 1.0.0 RC6 již nejen počítá správně, ale je také výrazně rychlejší než standardní Python3 a přitom nevyžaduje žádné změny kódu. Dovolil jsem si tedy Petra vyzpovídat a zeptat se jej, jak to dokázal.

Obsah

[editovat] Pracuješ v pražské pobočce OracleLabs. Co tu vlastně děláš?

Posledních pár měsíců pracuji na implementaci jazyka Python v Graal VM. Před tím, než jsem začal pracovat v Oracle Labs, tak jsem dělal pár editorů do NetBeans IDE. V NetBeans jsem se naučil hodně o lexování, parsovaní, AST a mnoho dalších věcí, které se týkají analýzy zdrojového kódu. Tohle mi určitě pomohlo v Oracle Labs, ale i tak je to jen malá část toho, co potřebují vědět nyní.

[editovat] Co jsi zkoumal nejdříve? Proč to nefunguje správně?

U implementace jazyka Pythonu do Graal VM nejsem od začátku. Nastoupil jsem již do rozjetého projektu, což není většinou jednoduché u projektů jako je tento. Prvních pár týdnů jsem implementoval Math modul, na kterém jsem se učil základní věci. Vlastně se pořád učím.

Občas zkouším rozjet náhodné scripty, abychom viděli, jak je na tom naše implementace. Jednak tím testujeme možné chyby a jednak také sleduji performance. Když jsem narazil na článek na Root.cz, kde byla porovnávána rychlost výpočtu obrázku různého rozlišení na základě Mandelbrotovy množiny, zkusil jsem autorův Python skript pustit také na naší implementaci. Nejdříve jsem musel doimplementovat asi dvě specializace v naší implementaci, abychom byli schopni skript spustit. To bylo jednoduché a otázka několik minut.

[editovat] Co to je ta specializace?

TBD

Jenže po spuštění jsem zjistil, že čas který je potřeba pro výpočet obrázku je několikanásobně větší než je potřeba pro výpočet toho samého obrázku v CPython. Problém byl v tom, že algoritmus vypočítané barvy jednotlivých bodů ukládá do stringu a nakonec celý string je vypsán na standartní výstup, který je přesměrován do souboru. Asi si řeknete, že to není ideální řešení, nicméně je to zdrojový kód z praxe.

[editovat] Proč to vlastně bylo tak pomalé? A jak jsi na to přišel?

Tady narážíme na problém zpracování stringu v jazyku Java, což je jazyk ve kterém je naše implementace napsaná. Sčítání stringů v Javě je poměrně rychlá, ale ovšem jen do té doby, než začne docházet paměť. Dříve nebo později se zavolá Arrays.copyof a tento příkaz vyžaduje souvislou volnou paměť pro vytvoření nového pole. Pokud velikost volné paměti je menší, než požadovaná velikost nového pole, dostanete OutOfMemoryException a končíte. To je ta lepší varianta z hlediska performance. Horší situace je, když volná paměť je, ale vytvářené pole se nevejde do žádného souvislého místa v paměti. V tu chvíli se zapíná GC a snaží se paměť uvolnit, tak aby se nové pole vešlo na jedno místo. Za špatných podmínek toto může trvat i několik desítek sekund. Nechci úplně zabíhat do podrobností, to by bylo na samostatný článek.

Pokud někdo zná Graal a Truffle, tak ví, že jednotlivé jazyky lze běhat buď v JVM nebo SVM módu. Kód předkompilovaný pomocí SVM startuje mnohonásobně rychleji než v JVM. Jenže tady jsem narazil na chybu v SVM, která právě zahrnuje chování Arrays.copyof a čas, který byl potřeba pro běžení skriptu na generování obrázku o velikosti 1024x1024 bodů, byl 15 minut.

[editovat] Jak jsi to zrychloval?

[editovat] Co si myslíš o Pythonu jako jazyku?

[editovat] Plánuješ to ještě nějak zrychlit?