S temi nasveti analizirajte svojo kodo in odkrijte, kje je najbolj ali najmanj učinkovita.

Ker v Pythonu "obstaja več kot en način za to", je iskanje pomnilniško najučinkovitejšega pristopa za nekatera opravila lahko izziv. Tukaj lahko pomaga profiler pomnilnika. Ocena pomnilniškega profila vaše kode poleg sledenja uhajanju pomaga ugotoviti, katera koda je pomnilniško učinkovita.

Ne glede na to, ali razvijate model strojnega učenja ali spletno mesto s Pythonom, lahko ocenite profil pomnilnika za skripte, posamezne vrstice kode ali funkcije.

Ocenjevanje pomnilniškega profila vaše celotne baze kode je morda nepraktično, saj lahko to močno upočasni vašo aplikacijo. Najbolje je, da namesto tega selektivno profilirate funkcije ali metode, za katere sumite, da porabijo več pomnilnika. Toda tudi če želite to narediti za svojo celotno aplikacijo, boste morda želeli nameniti izoliran modul za to.

V Pythonu je veliko knjižnic za profiliranje. Nekatere izmed najbolj priljubljenih so profil_pomnilnika, psutil, Tracemalloc, in pympler. Ta vadnica uporablja profil_pomnilnika in psutil.

instagram viewer

Medtem psutil je idealen za ocenjevanje skupne porabe pomnilnika pri izvajanju metode ali funkcije, profil_pomnilnika daje podrobnejše informacije o uporabi pomnilnika, vključno s trendi uporabe vrstice za strani in funkcionalne ravni skozi čas.

Za začetek namestite profil_pomnilnika v vaše virtualno okolje Python. To se tudi namesti psutil.

pip namestite memory_profiler

Pridobite velikost predmeta v pomnilniku

Profiliranje pomnilnika lahko začnete tako, da najprej izračunate velikost predmeta, ki ga nameravate uporabiti v pomnilniku.

Ta vrsta profiliranja je koristna na začetku razvoja – ko poskušate določiti, katero vrsto predmeta uporabiti v programu.

Če se na primer zataknete pri odločanju, katere metode uporabiti za doseganje naloge, recimo ustrezne Vrsta podatkov Python, lahko dobite velikost vsakega v bajtih, da ugotovite, kateri je lažji za vašo uporabo Ovitek.

The sys.getsizeof vgrajena metoda pride tukaj prav:

uvoz sys
natisni(f"velikost seznama: {sys.getsizeof([])} bajti")
natisni(f"velikost slovarja: {sys.getsizeof (dict)} bajti")
natisni(f"velikost tuple: {sys.getsizeof(())} bajti")
natisni(f"nastavljena velikost: {sys.getsizeof({})} bajtov")

Tukaj je rezultat:

Uporabite lahko tudi sys.getsizeof za primerjavo velikosti pomnilnika vgrajene funkcije in funkcije po meri.

Na primer, primerjajte to funkcijo dolžine po meri uporablja zanko Python for z vgrajenim len funkcija:

uvoz sys

defgetLength(ponovljiv):
štetje = 0

za jaz v ponovljiv:
štetje +=1

vrnitev štetje

natisni(f"Vgrajena funkcija dolžine: {sys.getsizeof (len)} bajti")
natisni(f"Funkcija dolžine po meri: {sys.getsizeof (getLength)} bajti")

Zgornja koda daje naslednje rezultate:

Vendar, medtem ko sys.getsizeof meri velikost predmeta v pomnilniku, upošteva le sam predmet in ne tistih, ki se nanj sklicujejo. Za to boste potrebovali podrobnejšo metodo profiliranja.

Poiščite pomnilniški profil funkcije Python

Podrobnejši profil pomnilnika za vsako vrstico kode funkcije lahko dobite z uporabo profil_pomnilnika paket. To vključuje dodajanje @profil dekorater za vašo funkcijo ali metodo:

uvoz pand
uvozi numpy
iz profila uvoza memory_profiler

razred Manipuliraj:
@profil
def manipulateData (samo):
df = pande. DataFrame({
'A' :[0, 3, numpy.nan, 10, 3, numpy.nan],
'B': [numpy.nan, "Pande", numpy.nan, "Pande", "Python", "JavaScript"],
})

df.fillna (metoda='bfill', inplace=True)
df.fillna (metoda='fill', inplace=True)
vrni str (df)

manip = Manipuliraj()
natisni (manip.manipulateData())

Zgornja koda daje podroben spominski profil vsake vrstice kode v funkciji, kot je prikazano:

The Uporaba mem stolpec označuje porabo pomnilnika za določeno vrstico kode, medtem ko stolpec Prirastek stolpec prikazuje režijske stroške, ki jih prispeva vsaka vrstica. The pojavnost stolpec določa, kolikokrat vrstica kode dodeli ali sprosti pomnilnik.

Na primer, v zgornjem izhodu se je vrstica 11 pojavila dvakrat s prirastkom pomnilnika 0,1 MiB (Mebibajt), kar je povečalo uporabo pomnilnika na 55,4 MiB. Vrstici 19 in 22 sta prav tako prispevali 0,2 MiB oziroma 0,3 MiB, tako da je skupna uporaba pomnilnika znašala 55,9 MiB.

Poiščite pomnilniški profil skripta Python po časovnem žigu

Profil pomnilnika celotnega skripta Python lahko ocenite tudi z uporabo profil_pomnilnika z vodenjem mprof ukaz v terminalu, kot je prikazano:

mprof zaženi script_name.py

Zgornji ukaz vzorči navedeni skript vsakih 0,1 s in samodejno ustvari a .dat datoteko v vašem trenutnem imeniku projekta.

Številke, ki sledijo MEM zapis so profili porabe pomnilnika skripta Python v določenem časovnem intervalu. Zadnje številke na desni predstavljajo časovni žig, ki ga je profiler zajel za vsako uporabo pomnilnika.

Dobite lahko tudi izris spominskega profila. To zahteva namestitev matplotlib:

pip namestite matplotlib

Ko je nameščen, zaženite mprof ukaz takole:

mprof plot

Tukaj je rezultat v tem primeru:

Zaženite profil pomnilnika skripta v namenski datoteki Python

Morda boste želeli profilirati za različne skripte Python. Zmoreš z uporabo namenskega modula Python prek Pythona podproces.

Na ta način lahko ločite svoj profiler pomnilnika od vaše baze kode in lokalno shranite izhod grafa:

uvoz podproces

subprocess.run([
'mprof', 'teči', '--include-children', 'missing.py'
])

# lokalno shranite rezultat izrisa
subprocess.run(['mprof', 'plot', '--output=output.jpg'])

Če želite zagnati pomnilniški profil skripta, morate zagnati samo datoteko Python, ki vsebuje zgornjo kodo. To ustvari graf pomnilniškega profila (izhod.jpg) v imeniku datotek:

Poiščite količino pomnilnika, uporabljenega pri izvajanju funkcije

Skupni profil pomnilnika metode ali funkcije med izvajanjem lahko najdete z uporabo psutil paket.

Na primer, za profil prejšnjega Manipulacija Pandas DataFrame metoda znotraj druge datoteke Python:

uvoz psutil
uvoz sys
uvoz os
sys.path.append (sys.path[0] + "/..")

# uvozite razred, ki vsebuje vašo metodo
od somecode.missing uvoz Manipulirati

# ustvari razred
manip = Manipuliraj()

proces = psutil. Proces (os.getpid())
začetni_pomnilnik = process.memory_info().rss

# zaženi ciljno metodo:
manip.manipulateData()

# pridobi informacije o pomnilniku po izvedbi
final_memory = process.memory_info().rss
porabljen_pomnilnik = končni_pomnilnik - začetni_pomnilnik
memory_consumed_mb = memory_consumed / (1024 * 1024)
natisni(f"Pomnilnik, ki ga porabi funkcija: {memory_consumed_mb:.2f} MB")

Zgornje ocenjuje skupni profil pomnilnika metode v megabajtih (MB), kot je prikazano:

Poiščite pomnilniški profil kodne vrstice v Jupyter Notebook

Če uporabljate iPython v Jupyter Notebooku, lahko izračunate pomnilniški profil enovrstične z uporabo profil_pomnilnika. Samo naložiti morate profil_pomnilnika v eni celici. Nato dodajte %memit čarobno funkcijo za vašo kodo v naslednjih celicah; to vrne največji pomnilnik in povečano velikost kode.

Ta metoda ne deluje z običajnimi skripti Python razen iPython v Jupyter Notebook.

Na primer:

Uporabite lahko tudi %memit čarobna funkcija v prenosniku Jypyter za profiliranje pomnilnika funkcije med izvajanjem:

Izboljšajte učinkovitost pomnilnika v kodi Python

Glede na težke naloge dvigovanja podatkov, za katere pogosto uporabljamo Python, potrebuje vsaka vrstica kode ustrezno optimizacijo za upravljanje uporabe pomnilnika. Medtem ko ima Python veliko vgrajenih funkcij Python, nereferencirani objekti povzročijo uhajanje pomnilnika.

Če ste v svojo kodno osnovo izpustili vsako sintakso Python, ki deluje, ne da bi upoštevali porabo pomnilnika, se boste morda želeli ozreti nazaj, preden greste predaleč.