Python-koodin optimointi profilointityökaluilla

Python Koodin Optimointi Profilointityokaluilla



Python-koodin suorituskyvyn parantaminen on kehittäjille arvokas taito. Profilointityökalut ovat tässä tapauksessa välttämättömiä ja helpottavat koodin rajoitusten ja tehottomuuden havaitsemista. Tässä artikkelissa tarkastellaan tapoja käyttää profilointityökaluja Python-ohjelmien parantamiseen. Hallitsemalla suoritusaikojen, muistin kulutuksen ja taajuuksien funktiokutsujen mittaamisen voimme parantaa tarkasti.

Python-koodin optimointi profilointityökaluilla

Google Colabin määrittäminen toimimaan Python-koodin optimoinnissa profilointityökaluilla. Aloitamme määrittämällä Google Colab -ympäristön. Jos olemme uusi Colabissa, se on tärkeä ja tehokas pilvipohjainen alusta, joka tarjoaa pääsyn Jupyter-muistikirjoihin ja useisiin Python-kirjastoihin. Pääsemme Colabiin käymällä osoitteessa (https://colab.research.google.com/) ja luomalla uuden Python-muistikirjan.

Tuo profilointikirjastot

Optimointimme perustuu profilointikirjastojen ammattitaitoiseen käyttöön. Kaksi tärkeää kirjastoa tässä yhteydessä ovat cProfile ja line_profiler.







tuonti cProfiili

tuonti line_profiler

'cProfile'-kirjasto on sisäänrakennettu Python-työkalu koodin profilointiin, kun taas 'line_profiler' on ulkoinen paketti, jonka avulla voimme mennä vielä syvemmälle analysoimalla koodia rivi riviltä.



Tässä vaiheessa luomme Python-mallikoodin Fibonacci-sekvenssin laskemiseksi rekursiivisen funktion avulla. Analysoidaan tätä prosessia tarkemmin. Fibonacci-sekvenssi on joukko lukuja, joissa jokainen peräkkäinen luku on kahden sitä edeltävän numeron summa. Se alkaa yleensä 0:lla ja 1:llä, joten sekvenssi näyttää 0, 1, 1, 2, 3, 5, 8, 13, 21 ja niin edelleen. Se on matemaattinen sekvenssi, jota käytetään yleisesti esimerkkinä ohjelmoinnissa sen rekursiivisen luonteen vuoksi.



Määrittelemme Python-funktion nimeltä 'Fibonacci' rekursiivisessa Fibonacci-funktiossa. Tämä funktio käyttää 'n' kokonaislukua argumenttinaan, joka edustaa paikkaa Fibonacci-sekvenssissä, jonka haluamme laskea. Haluamme paikantaa viidennen luvun Fibonacci-sekvenssistä, jos esimerkiksi 'n' on 5.





def fibonacci ( n ) :

Seuraavaksi luomme perustapauksen. Rekursion perustapaus on skenaario, joka päättää puhelut ja palauttaa ennalta määrätyn arvon. Kun Fibonacci-sekvenssissä 'n' on 0 tai 1, tiedämme jo tuloksen. 0. ja 1. Fibonacci-luku ovat 0 ja 1, vastaavasti.

jos n <= 1 :

palata n

Tämä 'if'-lause määrittää, onko 'n' pienempi vai yhtä suuri kuin 1. Jos on, palautetaan 'n' itse, koska lisärekursiota ei tarvita.



Rekursiivinen laskenta

Jos 'n' ylittää 1, jatkamme rekursiivista laskutoimitusta. Tässä tapauksessa meidän on löydettävä 'n':s Fibonacci-luku summaamalla '(n-1)' ja '(n-2)':s Fibonacci-luku. Saavutamme tämän tekemällä kaksi rekursiivista kutsua funktion sisällä.

muu :

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

Tässä 'fibonacci(n - 1)' laskee '(n-1)':nnen Fibonacci-luvun ja 'fibonacci(n - 2)' laskee '(n-2)':nnen Fibonacci-luvun. Lisäämme nämä kaksi arvoa saadaksesi halutun Fibonacci-luvun kohdassa 'n'.

Yhteenvetona voidaan todeta, että tämä 'fibonacci'-funktio laskee rekursiivisesti Fibonacci-luvut jakamalla ongelman pienempiin osaongelmiin. Se soittaa rekursiivisia kutsuja, kunnes se saavuttaa perustapaukset (0 tai 1), palauttaen tunnetut arvot. Jokaiselle muulle 'n':lle se laskee Fibonacci-luvun summaamalla kahden rekursiivisen kutsun tulokset '(n-1)' ja '(n-2)'.

Vaikka tämä toteutus on yksinkertaista Fibonacci-lukujen laskemiseen, se ei ole tehokkain. Myöhemmissä vaiheissa käytämme profilointityökaluja tunnistamaan ja optimoimaan sen suorituskykyrajoitukset paremman suoritusajan saavuttamiseksi.

Koodin profilointi CProfilella

Nyt profiloimme 'fibonacci'-toimintomme käyttämällä 'cProfilea'. Tämä profilointiharjoitus antaa käsityksen kunkin funktiokutsun käyttämästä ajasta.

cprofiler = cProfiili. Profiili ( )

cprofiler. ota käyttöön ( )

tulos = fibonacci ( 30 )

cprofiler. Poista käytöstä ( )

cprofiler. print_stats ( järjestellä = 'kumulatiivinen' )

Tässä segmentissä alustamme “cProfile”-objektin, aktivoimme profiloinnin, pyydämme “fibonacci”-funktiota arvolla “n=30”, deaktivoimme profiloinnin ja näytämme tilastot, jotka on lajiteltu kumulatiivisen ajan mukaan. Tämä alustava profilointi antaa meille korkean tason yleiskatsauksen siitä, mitkä toiminnot vievät eniten aikaa.

! pip install line_profiler

tuonti cProfiili

tuonti line_profiler

def fibonacci ( n ) :

jos n <= 1 :

palata n

muu :

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

cprofiler = cProfiili. Profiili ( )

cprofiler. ota käyttöön ( )

tulos = fibonacci ( 30 )

cprofiler. Poista käytöstä ( )

cprofiler. print_stats ( järjestellä = 'kumulatiivinen' )

Jos haluat profiloida koodin rivi riviltä line_profiler-sovelluksella yksityiskohtaisempaa analyysiä varten, käytämme 'line_profiler' -parametria segmentoimaan koodimme rivi riviltä. Ennen kuin käytät 'line_profiler', meidän on asennettava paketti Colab-tietovarastoon.

! pip install line_profiler

Nyt kun 'line_profiler' on valmis, voimme käyttää sitä 'fibonacci'-funktiossamme:

%load_ext line_profiler

def fibonacci ( n ) :

jos n <= 1 :

palata n

muu :

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

%lprun -f fibonacci fibonacci ( 30 )

Tämä katkelma alkaa lataamalla 'line_profiler' -laajennus, määrittelee 'fibonacci'-funktiomme ja käyttää lopuksi '%lprun' profiloimaan 'fibonacci'-funktion arvolla 'n=30'. Se tarjoaa suoritusaikojen segmentoinnin rivi riviltä ja selvittää tarkasti, mihin koodimme kuluttaa resurssejaan.

Kun profilointityökalut on suoritettu tulosten analysoimiseksi, sille esitetään joukko tilastoja, jotka osoittavat koodimme suorituskykyominaisuudet. Nämä tilastot sisältävät kussakin funktiossa käytetyn kokonaisajan ja kunkin koodirivin keston. Voimme esimerkiksi erottaa, että Fibonacci-funktio käyttää hieman enemmän aikaa identtisten arvojen uudelleenlaskentaan useita kertoja. Tämä on redundantti laskenta, ja se on selkeä alue, jossa optimointia voidaan soveltaa joko muistiin tallentamalla tai käyttämällä iteratiivisia algoritmeja.

Nyt teemme optimointeja, joissa havaitsimme mahdollisen optimoinnin Fibonacci-funktiossamme. Huomasimme, että funktio laskee samat Fibonacci-luvut uudelleen useita kertoja, mikä johtaa tarpeettomaan redundanssiin ja hitaampaan suoritusaikaan.

Tämän optimoimiseksi toteutamme muistiinpanon. Memoisointi on optimointitekniikka, jossa tallennetaan aiemmin lasketut tulokset (tässä tapauksessa Fibonacci-luvut) ja käytetään niitä tarvittaessa uudelleen sen sijaan, että ne laskettaisiin uudelleen. Tämä vähentää redundantteja laskelmia ja parantaa suorituskykyä erityisesti rekursiivisissa funktioissa, kuten Fibonacci-sekvenssissä.

Muistiinpanon toteuttamiseksi Fibonacci-funktiossamme kirjoitamme seuraavan koodin:

# Sanakirja laskettujen Fibonacci-lukujen tallentamiseen
fib_cache = { }
def fibonacci ( n ) :
jos n <= 1 :
palata n
# Tarkista, onko tulos jo välimuistissa
jos n sisään fib_cache:
palata fib_cache [ n ]
muu :
# Laske ja tallenna tulos välimuistiin
fib_cache [ n ] = fibonacci ( n - 1 ) + fibonacci ( n - 2 )
palata fib_cache [ n ] ,

Tässä 'fibonacci'-funktion muokatussa versiossa otamme käyttöön 'fib_cache'-sanakirjan, joka tallentaa aiemmin lasketut Fibonacci-luvut. Ennen kuin laskemme Fibonacci-luvun, tarkistamme, onko se jo välimuistissa. Jos on, palautamme välimuistissa olevan tuloksen. Muussa tapauksessa laskemme sen, säilytämme sen välimuistissa ja palautamme sen sitten.

Profiloinnin ja optimoinnin toistaminen

Optimoinnin (tapauksessamme muistiinpanon) toteuttamisen jälkeen on tärkeää toistaa profilointiprosessi, jotta tiedämme muutostemme vaikutuksen ja varmistamme, että paransimme koodin suorituskykyä.

Profilointi optimoinnin jälkeen

Voimme käyttää samoja profilointityökaluja 'cProfile' ja 'line_profiler' optimoidun Fibonacci-funktion profilointiin. Vertaamalla uusia profilointituloksia aikaisempiin, voimme mitata optimointimme tehokkuutta.

Näin voimme profiloida optimoidun 'fibonacci'-funktion käyttämällä 'cProfilea':

cprofiler = cProfiili. Profiili ( )

cprofiler. ota käyttöön ( )

tulos = fibonacci ( 30 )

cprofiler. Poista käytöstä ( )

cprofiler. print_stats ( järjestellä = 'kumulatiivinen' )

Käyttämällä 'line_profiler' -profiilia profiloimme sen rivi riviltä:

%lprun -f fibonacci fibonacci ( 30 )

Koodi:

# Sanakirja laskettujen Fibonacci-lukujen tallentamiseen
fib_cache = { }

def fibonacci ( n ) :
jos n <= 1 :
palata n
# Tarkista, onko tulos jo välimuistissa
jos n sisään fib_cache:
palata fib_cache [ n ]
muu :
# Laske ja tallenna tulos välimuistiin
fib_cache [ n ] = fibonacci ( n - 1 ) + fibonacci ( n - 2 )
palata fib_cache [ n ]
cprofiler = cProfiili. Profiili ( )
cprofiler. ota käyttöön ( )

tulos = fibonacci ( 30 )

cprofiler. Poista käytöstä ( )
cprofiler. print_stats ( järjestellä = 'kumulatiivinen' )
%lprun -f fibonacci fibonacci ( 30 )

Profilointitulosten analysoimiseksi optimoinnin jälkeen suoritusajat lyhenevät merkittävästi, erityisesti suurilla 'n'-arvoilla. Memoisoinnin vuoksi havaitsemme, että funktio käyttää nyt paljon vähemmän aikaa Fibonacci-lukujen uudelleenlaskentaan.

Nämä vaiheet ovat välttämättömiä optimointiprosessissa. Optimoinnissa tehdään tietoisia muutoksia koodiimme profiloinnista saatujen havaintojen perusteella, kun taas profiloinnin toistaminen varmistaa, että optimointimme tuottavat odotetut suorituskyvyn parannukset. Iteratiivisen profiloinnin, optimoinnin ja validoinnin avulla voimme hienosäätää Python-koodiamme tarjotaksemme paremman suorituskyvyn ja parantaaksemme sovelluksiemme käyttökokemusta.

Johtopäätös

Tässä artikkelissa keskustelimme esimerkistä, jossa optimoimme Python-koodin käyttämällä profilointityökaluja Google Colab -ympäristössä. Alusimme esimerkin asennuksella, toimme olennaiset profilointikirjastot, kirjoitimme mallikoodit, profiloimme sen käyttämällä sekä 'cProfilea' että 'line_profiler', laskemme tulokset, sovelsimme optimoinnit ja tarkensimme iteratiivisesti koodin suorituskykyä.