Kako optimizirati svoj Python kod pomoću alata za profiliranje

Kako Optimizirati Svoj Python Kod Pomocu Alata Za Profiliranje



Poboljšanje izvedbe Python koda je vrijedna vještina za programere. Alati za profiliranje ključni su u ovom slučaju i olakšavaju otkrivanje ograničenja koda i neučinkovitosti. Ovaj članak ispituje načine korištenja alata za profiliranje za poboljšanje Python programa. Savladavanjem mjerenja vremena izvršenja, potrošnje memorije i frekvencija poziva funkcija, možemo se precizno poboljšati.

Optimiziranje Python koda pomoću alata za profiliranje

Postavljanje Google Colaba za rad na optimiziranju Python koda s alatima za profiliranje, počinjemo postavljanjem Google Colab okruženja. Ako smo novi u Colabu, to je bitna, snažna platforma temeljena na oblaku koja omogućuje pristup Jupyter prijenosnim računalima i nizu Python biblioteka. Colabu pristupamo posjetom (https://colab.research.google.com/) i stvaranjem nove Python bilježnice.

Uvezite biblioteke profiliranja

Naša optimizacija oslanja se na vještu upotrebu knjižnica za profiliranje. Dvije važne biblioteke u ovom kontekstu su cProfile i line_profiler.







uvoz cProfil

uvoz line_profiler

Biblioteka “cProfile” je ugrađeni Python alat za profiliranje koda, dok je “line_profiler” vanjski paket koji nam omogućuje da idemo još dublje, analizirajući kod redak po redak.



U ovom koraku stvaramo primjer Python skripte za izračunavanje Fibonaccijevog niza pomoću rekurzivne funkcije. Analizirajmo ovaj proces dublje. Fibonaccijev niz je skup brojeva u kojem je svaki sljedeći broj zbroj dvaju brojeva prije njega. Obično počinje s 0 i 1, tako da niz izgleda kao 0, 1, 1, 2, 3, 5, 8, 13, 21 itd. To je matematički niz koji se obično koristi kao primjer u programiranju zbog svoje rekurzivne prirode.



Definiramo Python funkciju pod nazivom 'Fibonacci' u rekurzivnoj Fibonaccijevoj funkciji. Ova funkcija uzima cijeli broj “n” kao svoj argument, predstavljajući položaj u Fibonaccijevom nizu koji želimo izračunati. Želimo locirati peti broj u Fibonaccijevom nizu, na primjer, ako je 'n' jednako 5.





def fibonacci ( n ) :

Zatim uspostavljamo osnovni slučaj. Osnovni slučaj u rekurziji je scenarij koji prekida pozive i vraća unaprijed određenu vrijednost. U Fibonaccijevom nizu, kada je 'n' 0 ili 1, već znamo rezultat. 0. i 1. Fibonaccijev broj su 0 odnosno 1.

ako n <= 1 :

povratak n

Ova izjava 'if' određuje je li 'n' manji ili jednak 1. Ako jest, vraćamo sam 'n' jer nema potrebe za daljnjom rekurzijom.



Rekurzivni izračun

Ako 'n' premašuje 1, nastavljamo s rekurzivnim izračunom. U ovom slučaju, moramo pronaći “n”-ti Fibonaccijev broj zbrajanjem “(n-1)” i “(n-2)” Fibonaccijevog broja. To postižemo dvama rekurzivnim pozivima unutar funkcije.

drugo :

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

Ovdje “fibonacci(n – 1)” izračunava “(n-1)”-ti Fibonaccijev broj, a “fibonacci(n – 2)” izračunava “(n-2)”-ti Fibonaccijev broj. Zbrajamo ove dvije vrijednosti kako bismo dobili željeni Fibonaccijev broj na poziciji 'n'.

Ukratko, ova 'fibonaccijeva' funkcija rekurzivno izračunava Fibonaccijeve brojeve razbijanjem problema na manje podprobleme. Izvodi rekurzivne pozive dok ne dosegne osnovne slučajeve (0 ili 1), vraćajući poznate vrijednosti. Za bilo koji drugi 'n' izračunava Fibonaccijev broj zbrajanjem rezultata dvaju rekurzivnih poziva za '(n-1)' i '(n-2)'.

Iako je ova implementacija jednostavna za izračunavanje Fibonaccijevih brojeva, nije najučinkovitija. U kasnijim koracima upotrijebit ćemo alate za profiliranje kako bismo identificirali i optimizirali njegova ograničenja izvedbe za bolja vremena izvršenja.

Profiliranje koda s CProfile

Sada profiliramo našu 'fibonaccijevu' funkciju koristeći 'cProfile'. Ova vježba profiliranja pruža uvid u vrijeme koje troši svaki poziv funkcije.

cprofiler = cProfil. Profil ( )

cprofiler. omogućiti ( )

proizlaziti = fibonacci ( 30 )

cprofiler. onemogućiti ( )

cprofiler. ispis_statistike ( vrsta = 'kumulativno' )

U ovom segmentu inicijaliziramo “cProfile” objekt, aktiviramo profiliranje, zahtijevamo “fibonacci” funkciju s “n=30”, deaktiviramo profiliranje i prikazujemo statistiku koja je sortirana prema kumulativnom vremenu. Ovo početno profiliranje daje nam pregled na visokoj razini o tome koje funkcije troše najviše vremena.

! pip instaliraj line_profiler

uvoz cProfil

uvoz line_profiler

def fibonacci ( n ) :

ako n <= 1 :

povratak n

drugo :

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

cprofiler = cProfil. Profil ( )

cprofiler. omogućiti ( )

proizlaziti = fibonacci ( 30 )

cprofiler. onemogućiti ( )

cprofiler. ispis_statistike ( vrsta = 'kumulativno' )

Za profiliranje koda redak po redak s line_profilerom za detaljniju analizu, koristimo 'line_profiler' za segmentiranje našeg koda redak po redak. Prije upotrebe “line_profiler”, moramo instalirati paket u Colab repozitorij.

! pip instaliraj line_profiler

Sada kada imamo spreman 'line_profiler', možemo ga primijeniti na našu 'fibonacci' funkciju:

%load_ext line_profiler

def fibonacci ( n ) :

ako n <= 1 :

povratak n

drugo :

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

%lprun -f fibonacci fibonacci ( 30 )

Ovaj isječak počinje učitavanjem ekstenzije 'line_profiler', definira našu 'fibonacci' funkciju i na kraju koristi '%lprun' za profiliranje 'fibonacci' funkcije s 'n=30'. Nudi segmentaciju vremena izvršenja redak po redak, precizno razjašnjavajući gdje naš kod troši svoje resurse.

Nakon pokretanja alata za profiliranje za analizu rezultata, prikazat će se skup statistike koja prikazuje karakteristike izvedbe našeg koda. Ove statistike uključuju ukupno vrijeme potrošeno unutar svake funkcije i trajanje svake linije koda. Na primjer, možemo razlikovati da Fibonaccijeva funkcija ulaže malo više vremena u ponovno izračunavanje identičnih vrijednosti više puta. Ovo je redundantno izračunavanje i jasno je područje gdje se optimizacija može primijeniti, bilo putem memoizacije ili korištenjem iterativnih algoritama.

Sada radimo optimizacije tamo gdje smo identificirali potencijalnu optimizaciju u našoj Fibonaccijevoj funkciji. Primijetili smo da funkcija ponovno izračunava iste Fibonaccijeve brojeve više puta, što rezultira nepotrebnom redundancijom i sporijim vremenom izvršenja.

Da bismo to optimizirali, implementiramo memoizaciju. Memoizacija je optimizacijska tehnika koja uključuje pohranjivanje prethodno izračunatih rezultata (u ovom slučaju Fibonaccijevih brojeva) i njihovu ponovnu upotrebu po potrebi umjesto ponovnog izračunavanja. Ovo smanjuje suvišna izračunavanja i poboljšava izvedbu, posebno za rekurzivne funkcije poput Fibonaccijevog niza.

Da bismo implementirali memoizaciju u našu Fibonaccijevu funkciju, pišemo sljedeći kod:

# Rječnik za pohranjivanje izračunatih Fibonaccijevih brojeva
fib_cache = { }
def fibonacci ( n ) :
ako n <= 1 :
povratak n
# Provjerite je li rezultat već spremljen u predmemoriju
ako n u fib_cache:
povratak fib_cache [ n ]
drugo :
# Izračunajte i predmemorirajte rezultat
fib_cache [ n ] = fibonacci ( n - 1 ) + fibonacci ( n - 2 )
povratak fib_cache [ n ] ,

U ovoj modificiranoj verziji funkcije 'fibonacci', uvodimo rječnik 'fib_cache' za pohranjivanje prethodno izračunatih Fibonaccijevih brojeva. Prije izračuna Fibonaccijevog broja, provjeravamo je li već u cacheu. Ako jest, vraćamo predmemorirani rezultat. U svakom drugom slučaju, izračunavamo ga, čuvamo u predmemoriju i zatim vraćamo.

Ponavljanje profiliranja i optimizacije

Nakon implementacije optimizacije (memoizacija u našem slučaju), ključno je ponoviti proces profiliranja kako bismo znali učinak naših promjena i osigurali da smo poboljšali izvedbu koda.

Profiliranje nakon optimizacije

Možemo koristiti iste alate za profiliranje, 'cProfile' i 'line_profiler', za profiliranje optimizirane Fibonaccijeve funkcije. Uspoređujući nove rezultate profiliranja s prethodnima, možemo izmjeriti učinkovitost naše optimizacije.

Evo kako možemo profilirati optimiziranu 'fibonaccijevu' funkciju koristeći 'cProfile':

cprofiler = cProfil. Profil ( )

cprofiler. omogućiti ( )

proizlaziti = fibonacci ( 30 )

cprofiler. onemogućiti ( )

cprofiler. ispis_statistike ( vrsta = 'kumulativno' )

Koristeći 'line_profiler', profiliramo ga red po red:

%lprun -f fibonacci fibonacci ( 30 )

Kodirati:

# Rječnik za pohranjivanje izračunatih Fibonaccijevih brojeva
fib_cache = { }

def fibonacci ( n ) :
ako n <= 1 :
povratak n
# Provjerite je li rezultat već spremljen u predmemoriju
ako n u fib_cache:
povratak fib_cache [ n ]
drugo :
# Izračunajte i predmemorirajte rezultat
fib_cache [ n ] = fibonacci ( n - 1 ) + fibonacci ( n - 2 )
povratak fib_cache [ n ]
cprofiler = cProfil. Profil ( )
cprofiler. omogućiti ( )

proizlaziti = fibonacci ( 30 )

cprofiler. onemogućiti ( )
cprofiler. ispis_statistike ( vrsta = 'kumulativno' )
%lprun -f fibonacci fibonacci ( 30 )

Za analizu rezultata profiliranja nakon optimizacije bit će značajno smanjeno vrijeme izvršenja, posebno za velike 'n' vrijednosti. Zbog memoizacije, primjećujemo da funkcija sada troši puno manje vremena na ponovno izračunavanje Fibonaccijevih brojeva.

Ovi su koraci ključni u procesu optimizacije. Optimizacija uključuje unošenje informiranih izmjena u naš kod na temelju zapažanja dobivenih profiliranjem, dok ponavljanje profiliranja osigurava da naše optimizacije daju očekivana poboljšanja performansi. Iterativnim profiliranjem, optimiziranjem i provjerom valjanosti možemo fino podesiti naš Python kod kako bismo pružili bolju izvedbu i poboljšali korisničko iskustvo naših aplikacija.

Zaključak

U ovom smo članku raspravljali o primjeru u kojem smo optimizirali Python kod pomoću alata za profiliranje unutar okruženja Google Colab. Inicijalizirali smo primjer s postavkama, uvezli osnovne biblioteke za profiliranje, napisali uzorke kodova, profilirali ga koristeći i 'cProfile' i 'line_profiler', izračunali rezultate, primijenili optimizacije i iterativno poboljšali izvedbu koda.