Kaip optimizuoti savo Python kodą naudojant profiliavimo įrankius

Kaip Optimizuoti Savo Python Koda Naudojant Profiliavimo Irankius



Python kodo našumo gerinimas yra vertingas kūrėjų įgūdis. Šiuo atveju profiliavimo įrankiai yra būtini ir palengvina kodo apribojimų ir neefektyvumo aptikimą. Šiame straipsnyje nagrinėjami būdai, kaip naudoti profiliavimo įrankius Python programoms tobulinti. Įvaldę vykdymo laiko, atminties suvartojimo ir dažnių funkcijų iškvietimo matavimus, galime tiksliai tobulėti.

Python kodo optimizavimas naudojant profiliavimo įrankius

Nustatydami „Google Colab“, kad optimizuotų „Python“ kodą naudodami profiliavimo įrankius, pradedame nuo „Google Colab“ aplinkos nustatymo. Jei „Colab“ dar nesame nauji, tai svarbi, galinga debesies pagrindu sukurta platforma, suteikianti prieigą prie „Jupyter“ nešiojamųjų kompiuterių ir įvairių „Python“ bibliotekų. „Colab“ pasiekiame apsilankę (https://colab.research.google.com/) ir sukūrę naują „Python“ bloknotą.

Importuokite profiliavimo bibliotekas

Mūsų optimizavimas priklauso nuo profesionalaus profiliavimo bibliotekų naudojimo. Šiame kontekste dvi svarbios bibliotekos yra cProfile ir line_profiler.







importuoti cProfilis

importuoti linijos_profiliatorius

„cProfile“ biblioteka yra integruotas „Python“ įrankis kodui profiliuoti, o „line_profiler“ yra išorinis paketas, leidžiantis dar giliau analizuoti kodą eilutę po eilutės.



Šiame žingsnyje sukuriame Python scenarijaus pavyzdį, kad galėtume apskaičiuoti Fibonacci seką naudodami rekursinę funkciją. Panagrinėkime šį procesą išsamiau. Fibonačio seka yra skaičių rinkinys, kuriame kiekvienas iš eilės skaičius yra dviejų prieš jį einančių skaičių suma. Paprastai ji prasideda skaičiais 0 ir 1, todėl seka atrodo kaip 0, 1, 1, 2, 3, 5, 8, 13, 21 ir pan. Tai matematinė seka, kuri dėl savo rekursinio pobūdžio dažniausiai naudojama kaip pavyzdys programuojant.



Rekursyvinėje Fibonačio funkcijoje apibrėžiame Python funkciją, vadinamą „Fibonacci“. Šios funkcijos argumentas yra sveikasis skaičius „n“, reiškiantis Fibonačio sekos padėtį, kurią norime apskaičiuoti. Pavyzdžiui, mes norime rasti penktąjį skaičių Fibonačio sekoje, jei „n“ yra lygus 5.





def Fibonacci ( n ) :

Toliau nustatome bazinį atvejį. Bazinis atvejis rekursijoje yra scenarijus, kuris nutraukia skambučius ir grąžina iš anksto nustatytą reikšmę. Fibonačio sekoje, kai „n“ yra 0 arba 1, mes jau žinome rezultatą. 0 ir 1 Fibonačio skaičiai yra atitinkamai 0 ir 1.

jeigu n <= 1 :

grąžinti n

Šis „if“ teiginys nustato, ar „n“ yra mažesnis arba lygus 1. Jei taip, grąžiname patį „n“, nes nereikia tolesnės rekursijos.



Rekursinis skaičiavimas

Jei „n“ viršija 1, tęsiame rekursinį skaičiavimą. Šiuo atveju turime rasti „n“-ąjį Fibonačio skaičių, susumavę „(n-1)“ ir „(n-2)“ Fibonačio skaičius. Tai pasiekiame atlikdami du rekursinius iškvietimus funkcijoje.

Kitas :

grąžinti Fibonacci ( n - 1 ) + Fibonacci ( n - 2 )

Čia „fibonačio(n – 1)“ apskaičiuoja „(n-1)“-ąjį Fibonačio skaičių, o „fibonačio (n – 2)“ apskaičiuoja „(n-2)“-ąjį Fibonačio skaičių. Sudedame šias dvi reikšmes, kad gautume norimą Fibonačio skaičių „n“ padėtyje.

Apibendrinant, ši „fibonačio“ funkcija rekursyviai apskaičiuoja Fibonačio skaičius, suskaidydama problemą į smulkesnes problemas. Jis atlieka rekursinius skambučius, kol pasiekia bazinius atvejus (0 arba 1), grąžindamas žinomas reikšmes. Bet kuriam kitam „n“ jis apskaičiuoja Fibonačio skaičių, susumuodamas dviejų rekursinių skambučių „(n-1)“ ir „(n-2)“ rezultatus.

Nors šis įgyvendinimas yra paprastas norint apskaičiuoti Fibonačio skaičius, jis nėra pats efektyviausias. Vėlesniuose veiksmuose naudosime profiliavimo įrankius, kad nustatytų ir optimizuotume jo veikimo apribojimus, kad vykdymo laikas būtų geresnis.

Kodo profiliavimas naudojant CProfile

Dabar mes profiliuojame savo „fibonacci“ funkciją naudodami „cProfile“. Šis profiliavimo pratimas suteikia įžvalgų apie kiekvieno funkcijos iškvietimo laiką.

cprofiler = cProfilis. Profilis ( )

cprofiler. įjungti ( )

rezultatas = Fibonacci ( 30 )

cprofiler. išjungti ( )

cprofiler. print_stats ( rūšiuoti = 'kaupiamasis' )

Šiame segmente inicijuojame „cProfile“ objektą, suaktyviname profiliavimą, užklausiame „fibonacci“ funkcijos su „n=30“, išjungiame profiliavimą ir rodome statistiką, surūšiuotą pagal kaupiamąjį laiką. Šis pradinis profiliavimas suteikia mums aukšto lygio apžvalgą, kurios funkcijos užima daugiausiai laiko.

! pip install line_profiler

importuoti cProfilis

importuoti linijos_profiliatorius

def Fibonacci ( n ) :

jeigu n <= 1 :

grąžinti n

Kitas :

grąžinti Fibonacci ( n - 1 ) + Fibonacci ( n - 2 )

cprofileris = cProfilis. Profilis ( )

cprofileris. įjungti ( )

rezultatas = Fibonacci ( 30 )

cprofileris. išjungti ( )

cprofileris. print_stats ( rūšiuoti = 'kaupiamasis' )

Norėdami profiliuoti kodą eilutę po eilutės naudodami line_profiler ir atlikti išsamesnę analizę, naudojame kodo profilį segmentuoti savo kodo eilutę po eilutės. Prieš naudodami „line_profiler“, turime įdiegti paketą „Colab“ saugykloje.

! pip install line_profiler

Dabar, kai turime paruoštą „line_profiler“, galime pritaikyti jį savo „fibonacci“ funkcijai:

%load_ext line_profiler

def Fibonacci ( n ) :

jeigu n <= 1 :

grąžinti n

Kitas :

grąžinti Fibonacci ( n - 1 ) + Fibonacci ( n - 2 )

%lprun -f fibonacci fibonacci ( 30 )

Šis fragmentas prasideda įkeliant plėtinį „line_profiler“, apibrėžia mūsų „fibonacci“ funkciją ir galiausiai panaudoja „%lprun“, kad „fibonacci“ funkcija būtų profiliuota su „n=30“. Jis siūlo eilutę po eilutės segmentavimo vykdymo laiką, tiksliai išvalydamas, kur mūsų kodas eikvoja savo išteklius.

Paleidus profiliavimo įrankius rezultatams analizuoti, bus pateiktas statistikos masyvas, rodantis mūsų kodo veikimo charakteristikas. Ši statistika apima bendrą kiekvienos funkcijos laiką ir kiekvienos kodo eilutės trukmę. Pavyzdžiui, galime atskirti, kad Fibonačio funkcija investuoja šiek tiek daugiau laiko, kelis kartus perskaičiuodama identiškas vertes. Tai yra perteklinis skaičiavimas ir tai yra aiški sritis, kurioje galima pritaikyti optimizavimą, įrašant į atmintį arba naudojant iteracinius algoritmus.

Dabar atliekame optimizavimą, kai nustatėme galimą Fibonačio funkcijos optimizavimą. Pastebėjome, kad funkcija kelis kartus perskaičiuoja tuos pačius Fibonačio skaičius, todėl atsiranda nereikalingas perteklius ir lėtėja vykdymo laikas.

Norėdami tai optimizuoti, įdiegiame atmintinę. Atmintinė yra optimizavimo metodas, apimantis anksčiau apskaičiuotų rezultatų (šiuo atveju Fibonačio skaičių) saugojimą ir pakartotinį panaudojimą, kai reikia, užuot perskaičiavus. Tai sumažina perteklinius skaičiavimus ir pagerina našumą, ypač rekursinėms funkcijoms, tokioms kaip Fibonačio seka.

Norėdami įdiegti atmintinę savo Fibonačio funkcijoje, parašome šį kodą:

# Žodynas apskaičiuotiems Fibonačio skaičiams saugoti
fib_cache = { }
def Fibonacci ( n ) :
jeigu n <= 1 :
grąžinti n
# Patikrinkite, ar rezultatas jau išsaugotas talpykloje
jeigu n in fib_cache:
grąžinti fib_cache [ n ]
Kitas :
# Apskaičiuokite ir išsaugokite rezultatą
fib_cache [ n ] = Fibonacci ( n - 1 ) + Fibonacci ( n - 2 )
grąžinti fib_cache [ n ] ,

Šioje modifikuotoje „fibonačio“ funkcijos versijoje pristatome „fib_cache“ žodyną, kuriame saugomi anksčiau apskaičiuoti Fibonačio skaičiai. Prieš apskaičiuodami Fibonačio skaičių, patikriname, ar jis jau yra talpykloje. Jei taip, grąžiname talpykloje išsaugotą rezultatą. Visais kitais atvejais mes jį apskaičiuojame, laikome talpykloje ir grąžiname.

Profiliavimo ir optimizavimo kartojimas

Įgyvendinus optimizavimą (mūsų atveju – atmintyje), labai svarbu pakartoti profiliavimo procesą, kad žinotume pakeitimų poveikį ir įsitikintume, kad pagerinome kodo veikimą.

Profiliavimas po optimizavimo

Optimizuotai Fibonacci funkcijai profiliuoti galime naudoti tuos pačius profiliavimo įrankius „cProfile“ ir „line_profiler“. Palyginę naujus profiliavimo rezultatus su ankstesniais, galime išmatuoti savo optimizavimo efektyvumą.

Štai kaip galime profiliuoti optimizuotą „fibonacci“ funkciją naudodami „cProfile“:

cprofiler = cProfilis. Profilis ( )

cprofiler. įjungti ( )

rezultatas = Fibonacci ( 30 )

cprofiler. išjungti ( )

cprofiler. print_stats ( rūšiuoti = 'kaupiamasis' )

Naudodami „line_profiler“ profiliuojame eilutę po eilutės:

%lprun -f fibonacci fibonacci ( 30 )

Kodas:

# Žodynas apskaičiuotiems Fibonačio skaičiams saugoti
fib_cache = { }

def Fibonacci ( n ) :
jeigu n <= 1 :
grąžinti n
# Patikrinkite, ar rezultatas jau išsaugotas talpykloje
jeigu n in fib_cache:
grąžinti fib_cache [ n ]
Kitas :
# Apskaičiuokite ir išsaugokite rezultatą
fib_cache [ n ] = Fibonacci ( n - 1 ) + Fibonacci ( n - 2 )
grąžinti fib_cache [ n ]
cprofiler = cProfilis. Profilis ( )
cprofiler. įjungti ( )

rezultatas = Fibonacci ( 30 )

cprofiler. išjungti ( )
cprofiler. print_stats ( rūšiuoti = 'kaupiamasis' )
%lprun -f fibonacci fibonacci ( 30 )

Norint analizuoti profiliavimo rezultatus po optimizavimo, bus žymiai sutrumpintas vykdymo laikas, ypač didelėms „n“ reikšmėms. Dėl atminties įrašymo pastebime, kad funkcija dabar praleidžia daug mažiau laiko perskaičiuodama Fibonačio skaičius.

Šie veiksmai yra būtini optimizavimo procese. Optimizavimas apima informuotus kodo pakeitimus, pagrįstus stebėjimais, gautais iš profiliavimo, o kartojant profiliavimą užtikrinama, kad mūsų optimizavimas duos laukiamus našumo patobulinimus. Iteraciniu profiliavimu, optimizavimu ir patvirtinimu galime tiksliai sureguliuoti savo Python kodą, kad būtų užtikrintas geresnis našumas ir pagerinta mūsų programų vartotojo patirtis.

Išvada

Šiame straipsnyje aptarėme pavyzdį, kai optimizavome Python kodą naudodami profiliavimo įrankius „Google Colab“ aplinkoje. Mes inicijavome pavyzdį su sąranka, importavome pagrindines profiliavimo bibliotekas, parašėme pavyzdinius kodus, profiliavome naudodami „cProfile“ ir „line_profiler“, apskaičiavome rezultatus, pritaikėme optimizavimus ir iteratyviai patobulinome kodo veikimą.