Python Academy · Oppitunti

Profilointi cProfilella ja line_profilerilla

Etsikää suorittimen pullonkauloja cProfilella ja rivi riviltä tehtävällä profiloinnilla.

Oppitunti 3/413 vaihetta

Profilointi cProfilella ja line_profilerilla on ilmainen Python Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Python Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Python Academy-kurssilla on yhteensä 4 oppituntia.

Miksi profiloida?

Profilointi selvittää, mitkä funktiot kuluttavat eniten aikaa, ja auttaa kohdistamaan optimointityön. Profiloikaa aina ennen optimointia — älkää koskaan arvatko.

import cProfile

def slow():
    total = 0
    for i in range(1_000_000):
        total += i
    return total

cProfile.run("slow()")

cProfilen suorittaminen komentoriviltä

Profiloi koko skripti muuttamatta sitä: python -m cProfile -s cumtime script.py. Järjestä tulokset cumtime-, tottime- tai calls-arvon mukaan.

# python -m cProfile -s cumtime my_script.py
#
# ncalls  tottime  percall  cumtime  percall filename:lineno(function)
#   1000    0.500    0.001    2.100    0.002 utils.py:10(process)

cProfile koodissa

Luokaa cProfile.Profile-olio, ottakaa se käyttöön ja poistakaa se käytöstä, ja tulostakaa sitten tilastot pstats-moduulilla.

import cProfile, pstats, io

pr = cProfile.Profile()
pr.enable()

# ... code to profile ...

pr.disable()
stream = io.StringIO()
ps = pstats.Stats(pr, stream=stream).sort_stats("cumulative")
ps.print_stats(10)   # top 10
print(stream.getvalue())

pstats-suodatus

Suodattakaa profiloijan tuloste näyttämään vain tietyn moduulin tai funktion nimen mallin käyttämällä print_stats(pattern)-kutsua.

import cProfile, pstats

cProfile.run("my_function()", "profile.out")
stats = pstats.Stats("profile.out")
stats.sort_stats("tottime")
stats.print_stats("mymodule")   # only mymodule functions

line_profiler

line_profiler näyttää suoritusajan riveittäin, ei vain funktioittain — tämä on välttämätöntä funktion sisällä olevan kuormittavimman rivin löytämiseksi.

# pip install line_profiler
# Decorate target function:
from line_profiler import profile

@profile
def process(data):
    result = []
    for item in data:          # <- which line is slow?
        result.append(item*2)
    return result

# Run: kernprof -l -v script.py

kernprof CLI

kernprof -l script.py suorittaa skriptin rivikohtainen profilointi käytössä; -v näyttää raportin heti.

# kernprof -l -v script.py
#
# Line #  Hits  Time  Per Hit  % Time  Line Contents
# ======================================================
#     4    1  2.0   2.0       1.0    result = []
#     5  1000  120.0  0.1     60.0    for item in data:
#     6  1000   80.0  0.1     39.0        result.append(item*2)

Profilointi Jupyterissa

Jupyter tarjoaa %prun- (cProfile) ja %lprun- (line_profiler) taikakomennot.

# In a Jupyter cell:
# %prun -s cumulative my_function(data)

# %load_ext line_profiler
# %lprun -f my_function my_function(data)

Kuormituskohtien tunnistaminen

Keskittykää funktioihin, joiden kumulatiivinen aika on suurin (koko kutsuketju) ja joiden kokonaisaika on suurin (funktio itse ilman sen kutsumia funktioita).

# cumtime = total time including callees (find root cause)
# tottime = time in function itself (find where work happens)
#
# Optimise the function with highest tottime first

Ennenaikaisen optimoinnin välttäminen

Profiloi ensin ja optimoi sitten mitattu pullonkaula. Yleisiä tapoja nopeuttaa Pythonia ovat sisäänrakennettujen toimintojen käyttäminen, silmukoiden siirtäminen NumPyyn, toistuvien hakujen välimuistittaminen sekä C-koodin kutsuminen ctypes- tai cffi-kirjaston kautta.

# Before optimising:
# profile shows: process_row() 95% of time

# Speedup: vectorise with NumPy
import numpy as np
arr = np.array(data)
result = arr * 2   # 100x faster than Python loop

py-spy: otantaprofiloija

py-spy profiloi käynnissä olevia prosesseja muuttamatta koodia — liitä se käynnissä olevaan PID-tunnukseen.

# pip install py-spy

# Profile for 30 s and show flamegraph:
# py-spy top --pid 12345
# py-spy record -o profile.svg --pid 12345 --duration 30

Suorituskyvyn mittaaminen timeitillä

Käyttäkää timeit-moduulia tiettyjen lausekkeiden mikromittauksiin.

import timeit

result = timeit.timeit(
    "[x*2 for x in range(1000)]",
    number=10_000
)
print(f"{result:.3f} s for 10k runs")

Pikatarkistus

Mitä tottime näyttää cProfile-raportissa?

Kertaus

Käyttäkää cProfile-moduulia hitaiden funktioiden löytämiseen ja line_profiler-moduulia hitaimman rivin löytämiseen. Profiloi parametrilla -s cumtime juurisyiden löytämiseksi. Optimoi vain todistetut kuormituskohdat — käytä suurimpiin hyötyihin NumPyn vektorointia, välimuistia tai C-laajennuksia.

Aloita maksutta

Opi Python tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
76
Oppitunnit
320

Usein kysytyt kysymykset

Onko oppitunti ”Profilointi cProfilella ja line_profilerilla” ilmainen?

Kyllä – oppitunnin ”Profilointi cProfilella ja line_profilerilla” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Python Academy-kurssin, päivitä CoddyKit PROhon. Python Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Profilointi cProfilella ja line_profilerilla”?

Etsikää suorittimen pullonkauloja cProfilella ja rivi riviltä tehtävällä profiloinnilla. Harjoittelet Python Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Python Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Python Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Profilointi cProfilella ja line_profilerilla”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Python Academy-oppitunnilla?

Kyllä. Jokainen Python Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. CPythonin viitelaskenta
  2. Roskienkerääjä ja sykliset viittaukset
  3. Profilointi cProfilella ja line_profilerilla
  4. Muistiprofilointi tracemallocilla
← Takaisin: Python Academy