Kuidas optimeerida oma Pythoni koodi profiilitööriistade abil

Kuidas Optimeerida Oma Pythoni Koodi Profiilitooriistade Abil



Pythoni koodi jõudluse parandamine on arendajatele väärtuslik oskus. Profileerimistööriistad on sel juhul hädavajalikud ja hõlbustavad koodipiirangute ja ebatõhususe tuvastamist. Selles artiklis uuritakse viise, kuidas Pythoni programmide täiustamiseks kasutada profiilide koostamise tööriistu. Õppides täitmisaegade, mälutarbimise ja sageduste funktsioonikutsete mõõtmist, saame täpselt täiustada.

Pythoni koodi optimeerimine profiilitööriistade abil

Google Colabi seadistamine Pythoni koodi optimeerimiseks profiilide koostamise tööriistadega, alustame Google Colabi keskkonna seadistamisega. Kui oleme Colabis uustulnuk, on see oluline ja võimas pilvepõhine platvorm, mis pakub juurdepääsu Jupyteri sülearvutitele ja paljudele Pythoni teekidele. Pääseme Colabi juurde, külastades aadressi (https://colab.research.google.com/) ja luues uue Pythoni märkmiku.

Importige profiiliteegid

Meie optimeerimine põhineb profiiliteekide oskuslikul kasutamisel. Selles kontekstis on kaks olulist teeki cProfile ja line_profiler.







importida cProfiil

importida line_profiler

'cProfile' teek on sisseehitatud Pythoni tööriist koodi profileerimiseks, samas kui 'line_profiler' on väline pakett, mis võimaldab meil minna veelgi sügavamale, analüüsides koodi rida rea ​​haaval.



Selles etapis loome Pythoni näidisskripti Fibonacci jada arvutamiseks rekursiivse funktsiooni abil. Analüüsime seda protsessi põhjalikumalt. Fibonacci jada on arvude kogum, milles iga järjestikune arv on kahe eelneva summa summa. Tavaliselt algab see 0 ja 1-ga, nii et jada näeb välja nagu 0, 1, 1, 2, 3, 5, 8, 13, 21 jne. See on matemaatiline jada, mida selle rekursiivse olemuse tõttu kasutatakse programmeerimises tavaliselt näitena.



Rekursiivses Fibonacci funktsioonis määratleme Pythoni funktsiooni nimega 'Fibonacci'. Selle funktsiooni argumendiks on n täisarv, mis tähistab positsiooni Fibonacci jadas, mida tahame arvutada. Soovime leida Fibonacci jadas viienda numbri, näiteks kui 'n' on 5.





def fibonacci ( n ) :

Järgmisena loome alusjuhtumi. Rekursiooni baasjuhtum on stsenaarium, mis lõpetab kõned ja tagastab etteantud väärtuse. Fibonacci jadas, kui n on 0 või 1, teame tulemust juba. 0. ja 1. Fibonacci arv on vastavalt 0 ja 1.

kui n <= 1 :

tagasi n

See 'if' lause määrab, kas 'n' on väiksem kui 1 või võrdne sellega. Kui on, tagastame 'n' enda, kuna edasist rekursiooni pole vaja.



Rekursiivne arvutus

Kui “n” ületab 1, jätkame rekursiivse arvutusega. Sel juhul peame leidma 'n'-nda Fibonacci arvu, liites '(n-1)' ja '(n-2)' Fibonacci arvud. Selle saavutame funktsiooni sees kahe rekursiivse kõne tegemisega.

muidu :

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

Siin arvutab 'fibonacci(n - 1)' '(n-1)' Fibonacci arvu ja 'fibonacci(n - 2)' arvutab '(n-2)' Fibonacci arvu. Lisame need kaks väärtust, et saada soovitud Fibonacci arv positsioonis 'n'.

Kokkuvõttes arvutab see 'fibonacci' funktsioon rekursiivselt Fibonacci arvud, jagades probleemi väiksemateks alamprobleemideks. See teeb rekursiivseid kõnesid, kuni jõuab baasjuhtumiteni (0 või 1), tagastades teadaolevad väärtused. Mis tahes muu 'n' korral arvutab see Fibonacci arvu, liites kahe rekursiivse väljakutse '(n-1)' ja '(n-2)' tulemused.

Kuigi see rakendus on Fibonacci arvude arvutamiseks lihtne, pole see kõige tõhusam. Hilisemates etappides kasutame profiilide koostamise tööriistu, et tuvastada ja optimeerida selle jõudluspiirangud parema täitmisaja saavutamiseks.

Koodi profileerimine CProfile'iga

Nüüd profiilime oma 'fibonacci' funktsiooni, kasutades 'cProfile'. See profiilide koostamise harjutus annab ülevaate iga funktsioonikutsega kuluvast ajast.

cprofiler = cProfiil. Profiil ( )

cprofiler. lubada ( )

tulemus = fibonacci ( 30 )

cprofiler. keelata ( )

cprofiler. print_stats ( sorteerida = 'kumulatiivne' )

Selles segmendis initsialiseerime objekti 'cProfile', aktiveerime profiilide koostamise, taotleme funktsiooni 'fibonacci' väärtusega 'n=30', deaktiveerime profileerimise ja kuvame statistika, mis on sorteeritud kumulatiivse aja järgi. See esialgne profileerimine annab meile kõrgetasemelise ülevaate, millised funktsioonid kulutavad kõige rohkem aega.

! pip install line_profiler

importida cProfiil

importida line_profiler

def fibonacci ( n ) :

kui n <= 1 :

tagasi n

muidu :

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

cprofiler = cProfiil. Profiil ( )

cprofiler. lubada ( )

tulemus = fibonacci ( 30 )

cprofiler. keelata ( )

cprofiler. print_stats ( sorteerida = 'kumulatiivne' )

Täpsema analüüsi jaoks koodi rida-realt profileerimiseks funktsiooniga line_profiler kasutame koodi rida-realt segmenteerimiseks funktsiooni line_profiler. Enne line_profileri kasutamist peame installima paketi Colabi hoidlasse.

! pip install line_profiler

Nüüd, kui meil on 'line_profiler' valmis, saame seda rakendada oma 'fibonacci' funktsioonile:

%load_ext line_profiler

def fibonacci ( n ) :

kui n <= 1 :

tagasi n

muidu :

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

%lprun -f fibonacci fibonacci ( 30 )

See väljavõte algab laienduse „line_profiler” laadimisega, määratleb meie funktsiooni „fibonacci” ja lõpuks kasutab „%lprun” funktsiooni „fibonacci” profileerimiseks väärtusega „n=30”. See pakub täitmisaegade rida-realt segmenteerimist, selgitades täpselt, kuhu meie kood oma ressursse kulutab.

Pärast profiilide koostamise tööriistade käivitamist tulemuste analüüsimiseks kuvatakse see statistika massiiviga, mis näitab meie koodi jõudlusnäitajaid. See statistika hõlmab iga funktsiooni jaoks kulutatud koguaega ja iga koodirea kestust. Näiteks võime eristada, et Fibonacci funktsioon kulutab veidi rohkem aega, arvutades identseid väärtusi mitu korda ümber. See on üleliigne arvutus ja see on selge ala, kus optimeerimist saab rakendada kas memoiseerimise või iteratiivsete algoritmide abil.

Nüüd teeme optimeerimisi, kus tuvastasime oma Fibonacci funktsiooni potentsiaalse optimeerimise. Märkasime, et funktsioon arvutab samu Fibonacci numbreid mitu korda ümber, mille tulemuseks on tarbetu liiasus ja aeglasem täitmisaeg.

Selle optimeerimiseks rakendame memoiseerimise. Memoiseerimine on optimeerimistehnika, mis hõlmab eelnevalt arvutatud tulemuste (antud juhul Fibonacci numbrite) salvestamist ja vajaduse korral nende uuesti arvutamise asemel kasutamist. See vähendab üleliigseid arvutusi ja parandab jõudlust, eriti rekursiivsete funktsioonide puhul, nagu Fibonacci jada.

Fibonacci funktsioonis meeldejätmise rakendamiseks kirjutame järgmise koodi:

# Sõnastik arvutatud Fibonacci numbrite salvestamiseks
fib_cache = { }
def fibonacci ( n ) :
kui n <= 1 :
tagasi n
# Kontrollige, kas tulemus on juba vahemällu salvestatud
kui n sisse fib_cache:
tagasi fib_cache [ n ]
muidu :
# Arvutage tulemus ja salvestage see vahemällu
fib_cache [ n ] = fibonacci ( n - 1 ) + fibonacci ( n - 2 )
tagasi fib_cache [ n ] ,

Selles funktsiooni 'fibonacci' muudetud versioonis tutvustame varem arvutatud Fibonacci numbrite salvestamiseks sõnastikku 'fib_cache'. Enne Fibonacci numbri arvutamist kontrollime, kas see on juba vahemälus. Kui on, tagastame vahemällu salvestatud tulemuse. Igal muul juhul arvutame selle välja, hoiame seda vahemälus ja tagastame seejärel.

Profileerimise ja optimeerimise kordamine

Pärast optimeerimise (meie puhul meeldejätmise) rakendamist on oluline profiilide koostamise protsessi korrata, et teada saada meie muudatuste mõju ja tagada, et parandasime koodi jõudlust.

Profileerimine pärast optimeerimist

Optimeeritud Fibonacci funktsiooni profileerimiseks saame kasutada samu profileerimistööriistu 'cProfile' ja 'line_profiler'. Võrreldes uusi profileerimise tulemusi eelmistega, saame mõõta oma optimeerimise efektiivsust.

Siin on, kuidas saame optimeeritud 'fibonacci' funktsiooni 'cProfile' abil profileerida:

cprofiler = cProfiil. Profiil ( )

cprofiler. lubada ( )

tulemus = fibonacci ( 30 )

cprofiler. keelata ( )

cprofiler. print_stats ( sorteerida = 'kumulatiivne' )

Kasutades 'line_profiler', profileerime selle rida rea ​​haaval:

%lprun -f fibonacci fibonacci ( 30 )

Kood:

# Sõnastik arvutatud Fibonacci numbrite salvestamiseks
fib_cache = { }

def fibonacci ( n ) :
kui n <= 1 :
tagasi n
# Kontrollige, kas tulemus on juba vahemällu salvestatud
kui n sisse fib_cache:
tagasi fib_cache [ n ]
muidu :
# Arvutage tulemus ja salvestage see vahemällu
fib_cache [ n ] = fibonacci ( n - 1 ) + fibonacci ( n - 2 )
tagasi fib_cache [ n ]
cprofiler = cProfiil. Profiil ( )
cprofiler. lubada ( )

tulemus = fibonacci ( 30 )

cprofiler. keelata ( )
cprofiler. print_stats ( sorteerida = 'kumulatiivne' )
%lprun -f fibonacci fibonacci ( 30 )

Profiilide koostamise tulemuste analüüsimiseks pärast optimeerimist lühendatakse oluliselt täitmisaega, eriti suurte n-väärtuste puhul. Memoiseerimise tõttu märkame, et funktsioon kulutab nüüd Fibonacci arvude ümberarvutamisele palju vähem aega.

Need sammud on optimeerimisprotsessis olulised. Optimeerimine hõlmab meie koodi teadlike muudatuste tegemist profiilide koostamise käigus saadud tähelepanekute põhjal, samas kui profileerimise kordamine tagab, et meie optimeerimised annavad oodatud jõudluse paranemise. Iteratiivse profileerimise, optimeerimise ja valideerimise abil saame oma Pythoni koodi peenhäälestada, et pakkuda paremat jõudlust ja täiustada meie rakenduste kasutuskogemust.

Järeldus

Selles artiklis käsitlesime näidet, kus optimeerisime Pythoni koodi Google Colabi keskkonnas profiilitööriistade abil. Lähtestasime näite koos seadistusega, importisime olulised profiiliteegid, kirjutasime näidiskoodid, profileerisime selle nii 'cProfile' kui ka 'line_profiler' abil, arvutasime tulemused, rakendasime optimeerimisi ja viimistlesime iteratiivselt koodi jõudlust.