Ohjelmointi

CProfilen käyttäminen Python-koodin profilointiin

Python ei ehkä ole nopein kieli, mutta se on usein tarpeeksi nopea. Ja Python on ihanteellinen, kun ohjelmoijan aika on enemmän kuin suorittimen aika.

Siitä huolimatta, jos tietty Python-sovellus on viivästynyt, sinun ei tarvitse vain imeä sitä. Python-tulkin varastoasennuksen mukana tulevat työkalut voivat antaa sinulle yksityiskohtaista palautetta siitä, mitkä ohjelman osat ovat hitaita, ja tarjota vinkkejä niiden nopeuttamiseen.

CProfilen käyttö

cProfiili moduuli kerää tilastoja Python-ohjelman suoritusajasta. Se voi raportoida mistä tahansa koko sovelluksesta yhteen lausekkeeseen tai lausekkeeseen.

Tässä on leluesimerkki siitä, miten sitä käytetään cProfiili:

def add (x, y): x + = str (y) return x def add_2 (x, y): jos y% 20000 == 0: z = [] q: lle alueella (0,400000): z.endend ( q) def main (): a = [] n alueella alueella (0,200000): add (a, n) add_2 (a, n) jos __nimi__ == '__main__': tuo cProfile cProfile.run ('main ( ) ') 

Tämä esimerkki käyttää sovellusta main () ja analysoi main () ja kaikki main () puhelut. On myös mahdollista analysoida vain aosa ohjelman alkuosa, mutta yleisin käyttö aloittelijoille on koko ohjelman profilointi.

Suorita yllä oleva esimerkki ja sinut tervehditään jotain seuraavanlaista:

Tässä näkyy luettelo kaikista ohjelman soittamista toimintopyynnöistä sekä tilastotiedot kustakin:

  • Yläosassa (ensimmäinen rivi sinisenä) näemme profiloidussa ohjelmassa soitettujen puheluiden kokonaismäärän ja kokonaiskäyttöajan. Saatat myös nähdä kuvan, joka tarkoittaa "primitiivisiä kutsuja" ei-rekursiivinen puhelut tai suoraan toimintoon soitetut puhelut, jotka eivät puolestaan ​​soita itseään alaspäin puhelupinossa.
  • puhelut: Soitettujen puheluiden määrä. Jos näet kaksi numeroa vinoviivalla erotettuna, toinen numero on kyseisen toiminnon primitiivisten puheluiden määrä.
  • Tottime: Toiminnossa käytetty aika yhteensä, ei mukaan lukien puhelut muihin toimintoihin.
  • percall: Keskimääräinen aika per puhelu Tottime, johdettu ottamalla Tottime ja jakamalla se puhelut.
  • cumtime: Toiminnossa käytetty aika yhteensä, mukaan lukien puhelut muihin toimintoihin.
  • percall (# 2): Keskimääräinen aika kutsua kohden cumtime (cumtime jaettuna puhelut).
  • tiedostonimi: lineno: Kyseisen puhelun tiedostonimi, linjanumero ja funktion nimi.

CProfile-raporttien muokkaaminen

Oletuksena, cProfiili lajittelee lähdön standardinimellä, mikä tarkoittaa, että se lajittelee oikeassa reunassa olevan sarakkeen tekstin (tiedostonimi, rivinumero jne.).

Oletusmuoto on hyödyllinen, jos haluat yleisen ylhäältä alas -raportin jokaisesta yksittäisestä funktiokutsusta. Mutta jos yrität päästä pullonkaulan pohjaan, haluat todennäköisesti listata ensin ohjelman eniten aikaa vievät osat.

Voimme tuottaa nämä tulokset vetoamallacProfiili hieman eri tavalla. Huomaa, kuinka yllä olevan ohjelman alaosa voidaan muokata tilastojen lajittelemiseksi toisen sarakkeen mukaan (tässä tapauksessa puhelut):

jos __nimi__ == '__main__': Tuo cProfile, pstats profiler = cProfile.Profile () profiler.enable () main () profiler.disable () stats = pstats.Stats (profiler) .sort_stats ('ncalls') stats.print_stats () 

Tulokset näyttävät tältä:

Näin kaikki tämä toimii:

  • Komennon suorittamisen sijaan cProfile.run (), joka ei ole kovin joustava, luomme profiloinnin esine, profiloija.
  • Kun haluamme profiloida joitain toimintoja, soitamme ensin .ota käyttöön() profiler-objektin ilmentymässä, suorita sitten toiminto ja soita sitten .Poista käytöstä(). (Tämä on yksi tapa profiloida vain osa ohjelmaa.)
  • pstats moduulia käytetään profilointikohteen keräämien tulosten manipulointiin ja tulosten tulostamiseen.

Profileriobjektin ja pstats avulla voimme manipuloida kaapattuja profiilitietoja - esimerkiksi lajitella luodut tilastot eri tavalla. Tässä esimerkissä .sort_stats ('ncalls') lajittelee tilastot puhelut sarake. Muut lajitteluvaihtoehdot ovat käytettävissä.

CProfile-tulosten käyttäminen optimointiin

Lajitteluvaihtoehdot kohteelle cProfiili tuotoksen avulla voimme kiusata mahdolliset suorituskyvyn pullonkaulat ohjelmassa.

puhelut

Ensimmäinen ja merkittävin tieto, jonka avulla voit löytää cProfiili on mitä toimintoja kutsutaan useimmin puhelut sarake.

Pythonissa pelkkä toimintokutsun teko aiheuttaa suhteellisen suuren määrän yleiskustannuksia. Jos jotakin toimintoa kutsutaan toistuvasti tiukassa silmukassa, vaikka se ei olisikaan pitkäikäinen toiminto, se vaikuttaa suorituskykyyn.

Yllä olevassa esimerkissä funktio lisätä (ja toiminto lisää_2) kutsutaan toistuvasti silmukassa. Silmukan siirtäminen lisätä toiminto itsessään tai lisätä toimii kokonaan, korjata tämän ongelman.

Tottime

Toinen hyödyllinen tilastotieto, joka toimii ohjelmassa, viettää suurimman osan ajastaan ​​ohjelman suorittamiseen Tottime sarake.

Yllä olevassa esimerkissä lisää_2 -funktio käyttää silmukkaa simuloimaan kalliita laskutoimituksia, jotka työntävät sitä Tottime pisteet alkuun. Mikä tahansa toiminto, jolla on korkea Tottime pisteet ansaitsevat tarkan tarkastelun, varsinkin jos sitä kutsutaan monta kertaa tai tiukassa silmukassa.

Huomaa, että sinun on aina otettava huomioon yhteydessä jossa toimintoa käytetään. Jos toiminnolla on korkea Tottime mutta sitä kutsutaan vain kerran - esimerkiksi vain ohjelman käynnistyessä - se on vähemmän todennäköisesti pullonkaula. Jos kuitenkin yrität lyhentää käynnistysaikaa, sinun on tiedettävä, saako käynnistyksen yhteydessä kutsuttu toiminto kaiken muun odottamaan.

CProfile-tietojen vieminen

Jos haluat käyttää cProfiililuomia tilastoja edistyneemmillä tavoilla, voit viedä ne datatiedostoon:

stats = pstats.Stats (profiler) stats.dump_stats ('/ polku / kohteeseen / stats_file.dat') 

Tämä tiedosto voidaan lukea takaisin käyttämällä pstats lajitellaan tai näytetään pstats. Tietoja voidaan käyttää uudelleen myös muissa ohjelmissa. Kaksi esimerkkiä:

  • pyprof2kutsupuu tekee yksityiskohtaiset visualisoinnit ohjelman kutsukaaviosta ja käyttötilastoista profiilitiedoista. Tämä artikkeli tarjoaa yksityiskohtaisen todellisen esimerkin sen käytöstä.
  • snakeviz tuottaa myös visualisointeja cProfiili tietoja, mutta käyttää eri esitystapaa tiedoille - "auringonpurkaus" kuin pyprof2calltree "liekki" -kaavio.

Beyond cProfile Python-profilointia varten

cProfiili on tuskin ainoa tapa profiloida Python-sovellusta. cProfiili on varmasti yksi mukavimmista tavoista, koska se on mukana Pythonissa. Mutta muut ansaitsevat huomiota.

Yksi projekti, py-vakooja, rakentaa profiilin Python-sovellukselle ottamalla näytteeksi sen puhelutoiminnan. py-vakooja Sitä voidaan käyttää käynnissä olevan Python-sovelluksen tutkimiseen tarvitsematta pysäyttää ja käynnistää sitä uudelleen, eikä tarvitse muuttaa sen kooditietokantaa, joten sitä voidaan käyttää käyttöön otettujen sovellusten profilointiin. py-vakooja tuottaa myös joitain tilastoja Pythonin ajonaikaisista kustannuksista (esimerkiksi roskien keräyskulut), mikä cProfiili ei.