Pomoću ovih savjeta analizirajte svoj kod i otkrijte gdje je najučinkovitiji ili najmanje učinkovit.

Budući da u Pythonu "postoji više od jednog načina za to", pronalaženje memorijski najučinkovitijeg pristupa za neke zadatke može biti izazovno. Ovdje vam može pomoći memorijski profiler. Kao i praćenje curenja, procjena memorijskog profila vašeg koda pomaže u određivanju koji je kod memorijski učinkovit.

Bez obzira razvijate li model strojnog učenja ili web stranicu s Pythonom, možete procijeniti profil memorije za skripte, pojedinačne retke koda ili funkcije.

Procjena memorijskog profila vaše cijele baze koda može biti nepraktična, jer to može značajno usporiti vašu aplikaciju. Najbolje je da umjesto toga selektivno profilirate funkcije ili metode za koje sumnjate da bi mogle trošiti više memorije. Ali čak i ako to želite učiniti za cijelu svoju aplikaciju, možda ćete htjeti namijeniti izolirani modul za rukovanje time.

U Pythonu postoje mnoge knjižnice za profiliranje. Neki od najpopularnijih su

instagram viewer
memorijski_profiler, psutil, Tracemalloc, i pympler. Ovaj vodič koristi memorijski_profiler i psutil.

Dok psutil idealan je za procjenu ukupne potrošnje memorije za izvršavanje metode ili funkcije, memorijski_profiler daje detaljnije informacije o korištenju memorije, uključujući redak po red i trendove korištenja funkcionalne razine tijekom vremena.

Za početak instalirajte memorijski_profiler u vaše Python virtualno okruženje. Ovo se također instalira psutil.

pip instaliraj memory_profiler

Dohvatite veličinu objekta u memoriji

Svoje profiliranje memorije možete započeti tako da prvo izračunate veličinu objekta koji namjeravate koristiti u memoriji.

Ova vrsta profiliranja korisna je na početku razvoja—dok se pokušava odrediti koju vrstu objekta koristiti u programu.

Na primjer, ako zapnete pri odlučivanju koje ćete metode upotrijebiti za postizanje zadatka, recimo odgovarajuće Python tip podataka, možete dobiti veličinu svakog u bajtovima kako biste odredili koji je lakši za vašu upotrebu slučaj.

The sys.getsizeof ugrađena metoda ovdje dobro dolazi:

uvoz sustav
ispis(f"veličina popisa: {sys.getsizeof([])} bajtovi")
ispis(f"veličina rječnika: {sys.getsizeof (dict)} bajtovi")
ispis(f"veličina torke: {sys.getsizeof(())} bajtovi")
ispis(f"veličina skupa: {sys.getsizeof({})} bajtova")

Evo rezultata:

Također možete koristiti sys.getsizeof metoda za usporedbu veličine memorije ugrađene i prilagođene funkcije.

Na primjer, usporedite ovu prilagođenu funkciju duljine koja koristi Python for petlju s ugrađenim leća funkcija:

uvoz sustav

defgetLength(iterable):
brojati = 0

za ja u iterable:
brojati +=1

povratak računati

ispis(f"Ugrađena funkcija duljine: {sys.getsizeof (len)} bajtovi")
ispis(f"Funkcija prilagođene duljine: {sys.getsizeof (getLength)} bajtovi")

Gornji kod daje sljedeći izlaz:

Međutim, dok sys.getsizeof mjeri veličinu objekta u memoriji, uzima u obzir samo sam objekt, a ne one koji ga referenciraju. Za to će vam trebati detaljnija metoda profiliranja.

Pronađite profil memorije Python funkcije

Možete dobiti detaljniji memorijski profil svake linije koda funkcije pomoću memorijski_profiler paket. To uključuje dodavanje @profil dekorater za vašu funkciju ili metodu:

uvoz pande
import numpy
iz profila uvoza memory_profiler

klasa Manipulacija:
@profil
def manipulateData (self):
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)
povratak str (df)

manip = Manipuliraj()
ispis (manip.manipulateData())

Gornji kod daje detaljan memorijski profil svake linije koda u funkciji kao što je prikazano:

The Upotreba mema stupac označava korištenje memorije za određenu liniju koda, dok Povećanje stupac prikazuje režijske troškove koje doprinosi svaki redak. The Pojava stupac definira koliko puta linija koda dodjeljuje ili oslobađa memoriju.

Na primjer, u gornjem izlazu, redak 11 pojavio se dva puta s povećanjem memorije od 0,1 MiB (Mebibajt), povećavajući korištenje memorije na 55,4 MiB. Linije 19 i 22 također su doprinijele s 0,2 MiB odnosno 0,3 MiB, što ukupno iznosi 55,9 MiB.

Pronađite profil memorije Python skripte prema vremenskoj oznaci

Također možete procijeniti memorijski profil cijele Python skripte pomoću memorijski_profiler pokretanjem mprof naredba u terminalu kao što je prikazano:

mprof pokrenite script_name.py

Gornja naredba uzorkuje navedenu skriptu svakih 0,1 s i automatski stvara a .dat datoteku unutar direktorija vašeg trenutnog projekta.

Brojke koje slijede MEM notacija su profili korištenja memorije Python skripte u određenom vremenskom intervalu. Zadnje brojke s desne strane predstavljaju vremensku oznaku koju je profiler uhvatio za svaku upotrebu memorije.

Također možete dobiti dijagram memorijskog profila. To zahtijeva instalaciju matplotlib:

pip instaliraj matplotlib

Nakon instaliranja, pokrenite mprof naredba ovako:

mprof zaplet

Evo rezultata u ovom slučaju:

Pokrenite profil memorije skripte u namjenskoj Python datoteci

Možda biste željeli napraviti profil za različite Python skripte. Možeš ti to koristeći namjenski Python modul putem Pythona podproces.

Na ovaj način možete odvojiti svoj memorijski profiler od baze koda i spremiti izlaz grafikona lokalno:

uvoz podproces

subprocess.run([
'mprof', 'trčanje', '--uključi-djecu', 'missing.py'
])

# spremite ispis crteža lokalno
subprocess.run(['mprof', 'zemljište', '--output=output.jpg'])

Da biste pokrenuli memorijski profil skripte, trebate samo pokrenuti Python datoteku koja sadrži gornji kod. Ovo generira dijagram memorijskog profila (izlaz.jpg) u direktoriju datoteka:

Pronađite količinu memorije korištenu od izvršenja funkcije

Možete pronaći ukupni memorijski profil metode ili funkcije tijekom izvođenja pomoću psutil paket.

Na primjer, profilirati prethodni Pandas DataFrame manipulacija metoda unutar druge Python datoteke:

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

# uvezite klasu koja sadrži vašu metodu
iz somecode.nedostaje uvoz Manipulirati

# instancirajte klasu
manip = Manipuliraj()

proces = psutil. Proces (os.getpid())
početna_memorija = proces.memorija_info().rss

# pokrenite ciljnu metodu:
manip.manipulateData()

# dobiti informacije o memoriji nakon izvršenja
konačna_memorija = proces.memory_info().rss
potrošena_memorija = konačna_memorija - početna_memorija
memory_consumed_mb = memory_consumed / (1024 * 1024)
ispis(f"Memorija koju koristi funkcija: {memory_consumed_mb:.2f} MB")

Gore navedeno procjenjuje ukupni profil memorije metode u megabajtima (MB) kao što je prikazano:

Pronađite profil memorije retka koda u Jupyter Notebooku

Ako koristite iPython u Jupyter Notebooku, možete izračunati memorijski profil jednolinijskog zapisa pomoću memorijski_profiler. Vi samo trebate učitati memorijski_profiler u jednoj ćeliji. Zatim dodajte %memit čarobnu funkciju za vaš kod u sljedećim ćelijama; ovo vraća vršnu memoriju koda i povećanu veličinu.

Ova metoda ne radi s običnim Python skriptama osim iPythona u Jupyter Notebooku.

Na primjer:

Također možete koristiti %memit čarobna funkcija u Jypyter Notebooku za profiliranje memorije funkcije tijekom izvođenja:

Poboljšajte svoju memorijsku učinkovitost u svom Python kodu

Uzimajući u obzir teške zadatke prikupljanja podataka za koje često koristimo Python, svaki red koda treba odgovarajuću optimizaciju za upravljanje korištenjem memorije. Iako Python ima mnoge ugrađene Python funkcije, nereferencirani objekti rezultiraju curenjem memorije.

Ako ste izbacivali svaku Python sintaksu koja funkcionira u vašu bazu koda bez razmatranja upotrebe memorije, možda biste se trebali osvrnuti prije nego što odete predaleko.