Programování

Jak používat cProfile k profilování kódu Pythonu

Python nemusí být nejrychlejším jazykem v okolí, ale často je dostatečně rychlý. A Python je ideální, když na programátorském čase záleží více než na CPU.

To znamená, že pokud daná aplikace v Pythonu zaostává, nejste povinni ji jen nasát. Nástroje, které jsou součástí instalace skladu interpretu Pythonu, vám mohou poskytnout podrobnou zpětnou vazbu o tom, které části vašeho programu jsou pomalé, a nabídnout několik rad, jak je urychlit.

Jak používat cProfile

The cProfil modul shromažďuje statistiky o době provádění programu Python. Může hlásit cokoli od celé aplikace až po jediný příkaz nebo výraz.

Zde je příklad použití hračky cProfil:

def add (x, y): x + = str (y) návrat x def add_2 (x, y): pokud y% 20000 == 0: z = [] pro q v rozsahu (0,400000): z.append ( q) def main (): a = [] pro n v rozsahu (0,200000): add (a, n) add_2 (a, n) if __name__ == '__main__': import cProfile cProfile.run ('main ( ) ') 

Tento příklad spouští aplikaci hlavní() funkce a analyzuje výkon hlavní() a všechno hlavní() hovory. Je také možné analyzovat pouze ačást programu, ale nejběžnější použití pro začátečníky je profilovat celý program.

Spusťte výše uvedený příklad a budete uvítáni něčím jako následující výstup:

Zde je zobrazen seznam všech volání funkcí provedených programem spolu se statistikami o každém:

  • Nahoře (první řádek v modré barvě) vidíme celkový počet hovorů provedených v profilovaném programu a celkovou dobu provedení. Můžete také vidět číslo pro „primitivní volání“, což znamená nerekurzivní hovory nebo volání přímo na funkci, která se dále nevolá dále v zásobníku volání.
  • nvolání: Počet uskutečněných hovorů. Pokud vidíte dvě čísla oddělená lomítkem, druhé číslo je počet primitivních volání pro tuto funkci.
  • tottime: Celkový čas strávený funkcí, ne včetně volání dalších funkcí.
  • percall: Průměrná doba hovoru za tottime, odvozeno převzetím tottime a vydělením nvolání.
  • cumtime: Celkový čas strávený funkcí, včetně volání jiných funkcí.
  • percall (# 2): Průměrná doba hovoru za cumtime (cumtime děleno nvolání).
  • název souboru: lineno: Název souboru, číslo řádku a název funkce pro dané volání.

Jak upravit sestavy cProfile

Ve výchozím stavu, cProfil seřadí svůj výstup podle „standardního názvu“, což znamená, že seřadí podle textu v pravém sloupci (název souboru, číslo řádku atd.).

Výchozí formát je užitečný, pokud chcete pro referenci obecnou sestavu shora dolů o každém volání funkce. Pokud se však snažíte dostat na konec úzkého místa, budete pravděpodobně chtít nejdříve náročné části programu uvedené jako první.

Tyto výsledky můžeme dosáhnout vyvolánímcProfil trochu jinak. Všimněte si, jak lze spodní část výše uvedeného programu přepracovat, aby se statistika seřadila podle jiného sloupce (v tomto případě nvolání):

if __name__ == '__main__': import cProfile, pstats profiler = cProfile.Profile () profiler.enable () main () profiler.disable () stats = pstats.Stats (profiler) .sort_stats ('ncalls') stats.print_stats () 

Výsledky budou vypadat asi takto:

Všechno to funguje takto:

  • Místo provádění příkazu pomocí cProfile.run (), který není příliš flexibilní, vytváříme profilování objekt, profiler.
  • Když chceme profilovat nějakou akci, nejprve zavoláme .umožnit() na instanci objektu profileru, poté spusťte akci a poté zavolejte .disable (). (Toto je jeden způsob, jak profilovat pouze část programu.)
  • The pstats modul slouží k manipulaci s výsledky shromážděnými objektem profileru a k tisku těchto výsledků.

Kombinace objektu profileru a pstats umožňuje nám manipulovat se zachycenými daty profilu - například třídit generované statistiky odlišně. V tomto příkladu použití .sort_stats ('ncalls') seřadí statistiky podle nvolání sloupec. K dispozici jsou další možnosti řazení.

Jak používat výsledky cProfile pro optimalizaci

Dostupné možnosti řazení pro cProfil výstup nám umožňuje odstranit potenciální úzká místa výkonu v programu.

nvolání

První a nejvýznamnější informace, se kterou můžete odkrýt cProfil je, které funkce jsou nejčastěji volány pomocí nvolání sloupec.

V Pythonu pouhé provedení volání funkce vyvolá relativně velké množství režie. Pokud je některá funkce volána opakovaně v těsné smyčce, i když nejde o dlouhodobou funkci, je zaručeno, že to ovlivní výkon.

Ve výše uvedeném příkladu funkce přidat (a funkce přidat_2) je opakovaně volán ve smyčce. Přesunutí smyčky do přidat samotná funkce nebo vložení přidat fungovat úplně, vyřeší tento problém.

tottime

Další užitečné statistické podrobnosti, které funkce program tráví většinu času prováděním, pomocí tottime sloupec.

Ve výše uvedeném příkladu je přidat_2 Funkce používá smyčku k simulaci nějakého nákladného výpočtu, který tlačí jeho tottime skóre nahoru. Jakákoli funkce s vysokou tottime skóre si zaslouží bližší pohled, zvláště pokud je volán mnohokrát nebo v těsné smyčce.

Všimněte si, že musíte vždy zvážit kontext ve kterém je funkce použita. Pokud má funkce vysokou hodnotu tottime ale volá se pouze jednou - například pouze při spuštění programu - je méně pravděpodobné, že bude překážkou. Pokud se však snažíte zkrátit dobu spouštění, měli byste vědět, zda funkce volaná při spuštění umožňuje všem ostatním čekat.

Jak exportovat data cProfile

Pokud chcete použít cProfilStatistiky generované pokročilejšími způsoby, můžete je exportovat do datového souboru:

stats = pstats.Stats (profiler) stats.dump_stats ('/ path / to / stats_file.dat') 

Tento soubor lze znovu načíst pomocí pstats modul, poté seřazen nebo zobrazen pomocí pstats. Data mohou být znovu použita jinými programy. Dva příklady:

  • pyprof2calltree vykresluje podrobné vizualizace grafu volání programu a statistik využití z údajů profilu. Tento článek poskytuje podrobný příklad jeho použití v reálném světě.
  • hadeviz také generuje vizualizace z cProfil data, ale pro data používá jinou reprezentaci - graf „sunburst“ než graf „plamen“ pyprof2calltree.

Kromě cProfile pro profilování Pythonu

cProfil je stěží jediný způsob, jak profilovat aplikaci Pythonu. cProfil je určitě jedním z nejpohodlnějších způsobů, protože je dodáván s Pythonem. Ale ostatní si zaslouží pozornost.

Jeden projekt, py-špión, vytvoří profil pro aplikaci Python vzorkováním její aktivity volání. py-špión lze použít k prozkoumání spuštěné aplikace Pythonu, aniž byste ji museli zastavovat a restartovat, a aniž byste museli měnit její kódovou základnu, takže ji lze použít k profilování nasazených aplikací. py-špión také generuje některé statistiky o režii vzniklé za běhového prostředí Pythonu (například režie uvolňování paměti), která cProfil ne.