Kako optimizirati svojo kodo Python z orodji za profiliranje

Kako Optimizirati Svojo Kodo Python Z Orodji Za Profiliranje



Izboljšanje zmogljivosti kode Python je dragocena veščina za razvijalce. Orodja za profiliranje so v tem primeru bistvena in olajšajo odkrivanje omejitev kode in neučinkovitosti. Ta članek preučuje načine uporabe orodij za profiliranje za izboljšanje programov Python. Z obvladovanjem merjenja časov izvajanja, porabe pomnilnika in funkcijskega klica frekvenc se lahko natančno izboljšamo.

Optimizacija kode Python z orodji za profiliranje

Pri nastavitvi Google Colaba za optimizacijo kode Python z orodji za profiliranje začnemo z nastavitvijo okolja Google Colab. Če smo novi v Colabu, je to bistvena, zmogljiva platforma v oblaku, ki omogoča dostop do zvezkov Jupyter in vrste knjižnic Python. Do Colaba dostopamo tako, da obiščemo (https://colab.research.google.com/) in ustvarimo nov zvezek Python.

Uvozite knjižnice profiliranja

Naša optimizacija temelji na spretni uporabi profilnih knjižnic. Dve pomembni knjižnici v tem kontekstu sta cProfile in line_profiler.







uvoz cProfil

uvoz line_profiler

Knjižnica »cProfile« je vgrajeno orodje Python za profiliranje kode, medtem ko je »line_profiler« zunanji paket, ki nam omogoča, da gremo še globlje in analiziramo kodo vrstico za vrstico.



V tem koraku ustvarimo vzorčni skript Python za izračun Fibonaccijevega zaporedja z uporabo rekurzivne funkcije. Analizirajmo ta proces podrobneje. Fibonaccijevo zaporedje je niz števil, v katerem je vsako naslednje število vsota dveh pred njim. Običajno se začne z 0 in 1, zato je zaporedje videti kot 0, 1, 1, 2, 3, 5, 8, 13, 21 itd. To je matematično zaporedje, ki se običajno uporablja kot primer v programiranju zaradi svoje rekurzivne narave.



V rekurzivni Fibonaccijevi funkciji definiramo funkcijo Python, imenovano 'Fibonacci'. Ta funkcija za svoj argument sprejme celo število »n«, ki predstavlja položaj v Fibonaccijevem zaporedju, ki ga želimo izračunati. Želimo poiskati peto številko v Fibonaccijevem zaporedju, na primer, če je 'n' enako 5.





def fibonacci ( n ) :

Nato vzpostavimo osnovni primer. Osnovni primer pri rekurziji je scenarij, ki prekine klice in vrne vnaprej določeno vrednost. V Fibonaccijevem zaporedju, ko je 'n' 0 ali 1, že poznamo rezultat. 0. in 1. Fibonaccijevo število sta 0 oziroma 1.

če n <= 1 :

vrnitev n

Ta stavek »če« določa, ali je »n« manjši ali enak 1. Če je, vrnemo sam »n«, saj ni potrebe po nadaljnji rekurziji.



Rekurzivno računanje

Če 'n' presega 1, nadaljujemo z rekurzivnim izračunom. V tem primeru moramo najti 'n'-to Fibonaccijevo število tako, da seštejemo '(n-1)' in '(n-2)' Fibonaccijevo število. To dosežemo z dvema rekurzivnima klicema znotraj funkcije.

drugače :

vrnitev fibonacci ( n - 1 ) + fibonacci ( n - 2 )

Tukaj »fibonacci(n – 1)« izračuna »(n-1)« Fibonaccijevo število, »fibonacci(n – 2)« pa izračuna »(n-2)« Fibonaccijevo število. Ti dve vrednosti seštejemo, da dobimo želeno Fibonaccijevo število na položaju 'n'.

Če povzamemo, ta »fibonaccijeva« funkcija rekurzivno izračuna Fibonaccijeva števila tako, da problem razdeli na manjše podprobleme. Izvaja rekurzivne klice, dokler ne doseže osnovnih primerov (0 ali 1), pri čemer vrne znane vrednosti. Za kateri koli drug 'n' izračuna Fibonaccijevo število tako, da sešteje rezultate dveh rekurzivnih klicev za '(n-1)' in '(n-2)'.

Čeprav je ta izvedba enostavna za izračun Fibonaccijevih števil, ni najbolj učinkovita. V kasnejših korakih bomo uporabili orodja za profiliranje, da prepoznamo in optimiziramo njegove omejitve delovanja za boljše čase izvajanja.

Profiliranje kode s CProfile

Zdaj profiliramo našo 'fibonaccijevo' funkcijo z uporabo 'cProfile'. Ta vaja profiliranja zagotavlja vpogled v čas, ki ga porabi vsak klic funkcije.

cprofiler = cProfil. Profil ( )

cprofiler. omogočiti ( )

rezultat = fibonacci ( 30 )

cprofiler. onemogočiti ( )

cprofiler. print_stats ( vrsta = 'kumulativno' )

V tem segmentu inicializiramo objekt “cProfile”, aktiviramo profiliranje, zahtevamo funkcijo “fibonacci” z “n=30”, deaktiviramo profiliranje in prikažemo statistiko, ki je razvrščena po kumulativnem času. To začetno profiliranje nam daje pregled na visoki ravni, katere funkcije porabijo največ časa.

! pip namestite line_profiler

uvoz cProfil

uvoz line_profiler

def fibonacci ( n ) :

če n <= 1 :

vrnitev n

drugače :

vrnitev fibonacci ( n - 1 ) + fibonacci ( n - 2 )

cprofiler = cProfil. Profil ( )

cprofiler. omogočiti ( )

rezultat = fibonacci ( 30 )

cprofiler. onemogočiti ( )

cprofiler. print_stats ( vrsta = 'kumulativno' )

Za profiliranje kode vrstico za vrstico z line_profilerjem za podrobnejšo analizo uporabimo »line_profiler« za segmentiranje naše kode vrstico za vrstico. Pred uporabo »line_profiler« moramo namestiti paket v repozitorij Colab.

! pip namestite line_profiler

Zdaj, ko imamo pripravljen 'line_profiler', ga lahko uporabimo za našo 'fibonaccijevo' funkcijo:

%load_ext line_profiler

def fibonacci ( n ) :

če n <= 1 :

vrnitev n

drugače :

vrnitev fibonacci ( n - 1 ) + fibonacci ( n - 2 )

%lprun -f fibonacci fibonacci ( 30 )

Ta delček se začne z nalaganjem razširitve »line_profiler«, definira našo funkcijo »fibonacci« in na koncu uporabi »%lprun« za profiliranje funkcije »fibonacci« z »n=30«. Ponuja segmentacijo časov izvajanja po vrsticah, pri čemer je natančno razvidno, kje naša koda porablja svoje vire.

Po zagonu orodij za profiliranje za analizo rezultatov bo predstavljen niz statističnih podatkov, ki prikazuje značilnosti delovanja naše kode. Ti statistični podatki vključujejo skupni čas, porabljen za vsako funkcijo, in trajanje vsake vrstice kode. Na primer, lahko ločimo, da Fibonaccijeva funkcija vloži nekaj več časa v večkratno preračunavanje enakih vrednosti. To je redundantno računanje in je jasno področje, kjer je mogoče uporabiti optimizacijo, bodisi z memoizacijo ali z uporabo iterativnih algoritmov.

Zdaj izvajamo optimizacije, kjer smo identificirali potencialno optimizacijo v naši Fibonaccijevi funkciji. Opazili smo, da funkcija večkrat preračuna ista Fibonaccijeva števila, kar ima za posledico nepotrebno redundanco in počasnejši čas izvajanja.

Da bi to optimizirali, izvajamo memoization. Memoizacija je tehnika optimizacije, ki vključuje shranjevanje predhodno izračunanih rezultatov (v tem primeru Fibonaccijevih števil) in njihovo ponovno uporabo, ko je to potrebno, namesto ponovnega izračuna. To zmanjša odvečne izračune in izboljša zmogljivost, zlasti za rekurzivne funkcije, kot je Fibonaccijevo zaporedje.

Za izvedbo memoizacije v naši Fibonaccijevi funkciji napišemo naslednjo kodo:

# Slovar za shranjevanje izračunanih Fibonaccijevih števil
fib_cache = { }
def fibonacci ( n ) :
če n <= 1 :
vrnitev n
# Preverite, ali je rezultat že predpomnjen
če n v fib_cache:
vrnitev fib_cache [ n ]
drugače :
# Izračunajte in predpomnite rezultat
fib_cache [ n ] = fibonacci ( n - 1 ) + fibonacci ( n - 2 )
vrnitev fib_cache [ n ] ,

V tej spremenjeni različici funkcije »fibonacci« uvajamo slovar »fib_cache« za shranjevanje predhodno izračunanih Fibonaccijevih števil. Preden izračunamo Fibonaccijevo število, preverimo, ali je že v predpomnilniku. Če je, vrnemo predpomnjeni rezultat. V vsakem drugem primeru ga izračunamo, shranimo v predpomnilnik in nato vrnemo.

Ponavljanje profiliranja in optimizacije

Po izvedbi optimizacije (v našem primeru memoizacija) je ključnega pomena, da ponovite postopek profiliranja, da poznate vpliv naših sprememb in zagotovite, da smo izboljšali delovanje kode.

Profiliranje po optimizaciji

Za profiliranje optimizirane Fibonaccijeve funkcije lahko uporabimo ista orodja za profiliranje, »cProfile« in »line_profiler«. S primerjavo novih rezultatov profiliranja s prejšnjimi lahko izmerimo učinkovitost naše optimizacije.

Tukaj je opisano, kako lahko profiliramo optimizirano 'fibonaccijevo' funkcijo z uporabo 'cProfile':

cprofiler = cProfil. Profil ( )

cprofiler. omogočiti ( )

rezultat = fibonacci ( 30 )

cprofiler. onemogočiti ( )

cprofiler. print_stats ( vrsta = 'kumulativno' )

Z uporabo »line_profilerja« profiliramo vrstico za vrstico:

%lprun -f fibonacci fibonacci ( 30 )

Koda:

# Slovar za shranjevanje izračunanih Fibonaccijevih števil
fib_cache = { }

def fibonacci ( n ) :
če n <= 1 :
vrnitev n
# Preverite, ali je rezultat že predpomnjen
če n v fib_cache:
vrnitev fib_cache [ n ]
drugače :
# Izračunajte in predpomnite rezultat
fib_cache [ n ] = fibonacci ( n - 1 ) + fibonacci ( n - 2 )
vrnitev fib_cache [ n ]
cprofiler = cProfil. Profil ( )
cprofiler. omogočiti ( )

rezultat = fibonacci ( 30 )

cprofiler. onemogočiti ( )
cprofiler. print_stats ( vrsta = 'kumulativno' )
%lprun -f fibonacci fibonacci ( 30 )

Za analizo rezultatov profiliranja po optimizaciji bodo znatno skrajšani časi izvajanja, zlasti za velike vrednosti »n«. Zaradi memoizacije opazimo, da funkcija zdaj porabi veliko manj časa za preračunavanje Fibonaccijevih števil.

Ti koraki so bistveni v procesu optimizacije. Optimizacija vključuje sprejemanje premišljenih sprememb naše kode na podlagi opazovanj, pridobljenih s profiliranjem, medtem ko ponavljajoče se profiliranje zagotavlja, da naše optimizacije prinesejo pričakovane izboljšave zmogljivosti. Z iterativnim profiliranjem, optimiziranjem in preverjanjem lahko natančno prilagodimo našo kodo Python, da zagotovimo boljšo zmogljivost in izboljšamo uporabniško izkušnjo naših aplikacij.

Zaključek

V tem članku smo obravnavali primer, kjer smo optimizirali kodo Python z orodji za profiliranje v okolju Google Colab. Primer smo inicializirali z nastavitvijo, uvozili bistvene knjižnice za profiliranje, napisali vzorčne kode, ga profilirali z uporabo »cProfile« in »line_profiler«, izračunali rezultate, uporabili optimizacije in iterativno izboljšali delovanje kode.