Utilizați aceste sfaturi pentru a vă analiza codul și pentru a descoperi unde este cel mai sau mai puțin eficient.

Deoarece „există mai mult de o modalitate de a face acest lucru” în Python, găsirea celei mai eficiente abordări din punct de vedere al memoriei pentru unele sarcini poate fi o provocare. Aici poate ajuta un profiler de memorie. Pe lângă urmărirea scurgerilor, estimarea profilului de memorie al codului dvs. ajută la determinarea codului care este eficient din punct de vedere al memoriei.

Indiferent dacă dezvoltați un model de învățare automată sau un site web cu Python, puteți estima profilul de memorie pentru scripturi, linii de cod individuale sau funcții.

Estimarea profilului de memorie al întregii baze de cod ar putea fi nepractică, deoarece aceasta vă poate încetini în mod semnificativ aplicația. Cel mai bine este să profilați selectiv funcțiile sau metodele despre care bănuiți că ar putea consuma mai multă memorie. Dar chiar dacă doriți să faceți acest lucru pentru întreaga aplicație, este posibil să doriți să dedicați un modul izolat pentru a o gestiona.

instagram viewer

Există multe biblioteci de profilare în Python. Unele dintre cele mai populare sunt memorie_profiler, psutil, Tracemalloc, și pympler. Acest tutorial folosește memorie_profiler și psutil.

In timp ce psutil este ideal pentru estimarea consumului total de memorie al execuției unei metode sau funcție, memorie_profiler oferă informații mai detaliate de utilizare a memoriei, inclusiv tendințe de utilizare de-a lungul timpului de-a lungul timpului la nivel de funcțional.

Pentru a începe, instalați memorie_profiler în mediul dumneavoastră virtual Python. Se instalează și asta psutil.

pip install memory_profiler

Obțineți dimensiunea unui obiect din memorie

Puteți începe profilarea memoriei calculând mai întâi dimensiunea unui obiect pe care intenționați să îl utilizați în memorie.

Acest tip de profilare este util la începutul dezvoltării, în timp ce încearcă să determine ce tip de obiect să folosești într-un program.

De exemplu, dacă rămâneți blocat să decideți ce metode să utilizați pentru îndeplinirea unei sarcini, să zicem, cea potrivită Tip de date Python, puteți obține dimensiunea fiecăruia în octeți pentru a determina care este mai ușor pentru utilizarea dvs caz.

The sys.getsizeof metoda încorporată este utilă aici:

import sys
imprimare(f"dimensiunea listei: {sys.getsizeof([])} octeți")
imprimare(f"dicționar dimensiune: {sys.getsizeof (dict)} octeți")
imprimare(f"dimensiune tuplu: {sys.getsizeof(())} octeți")
imprimare(f"setare dimensiune: {sys.getsizeof({})} octeți")

Iată rezultatul:

De asemenea, puteți utiliza sys.getsizeof metodă de a compara dimensiunea memoriei unei funcții încorporate și personalizate.

De exemplu, comparați această funcție de lungime personalizată care folosește o buclă Python for cu încorporat len funcţie:

import sys

defgetLength(iterabil):
numără = 0

pentru i în iterabil:
numără +=1

întoarcere numara

imprimare(f"Funcția de lungime încorporată: {sys.getsizeof (len)} octeți")
imprimare(f"Funcția de lungime personalizată: {sys.getsizeof (getLength)} octeți")

Codul de mai sus oferă următoarea ieșire:

Cu toate acestea, în timp ce sys.getsizeof măsoară dimensiunea unui obiect în memorie, ține cont doar de obiectul în sine și nu de cei care îl fac referire. Pentru asta, veți avea nevoie de o metodă de profilare mai detaliată.

Găsiți profilul de memorie al unei funcții Python

Puteți obține un profil de memorie mai detaliat al fiecărei linii de cod a unei funcții folosind memorie_profiler pachet. Aceasta implică adăugarea @profil decorator la funcția sau metoda dvs.:

importa panda
import numpy
din profilul de import memory_profiler

Manipularea clasei:
@profil
def manipulateData (self):
df = panda. DataFrame({
„A” :[0, 3, numpy.nan, 10, 3, numpy.nan],
„B”: [numpy.nan, „Pandas”, numpy.nan, „Pandas”, „Python”, „JavaScript”],
})

df.fillna (method='bfill', inplace=True)
df.fillna (method='fill', inplace=True)
return str (df)

manip = Manipulare()
print (manip.manipulateData())

Codul de mai sus oferă un profil de memorie detaliat al fiecărei linii de cod din funcție, așa cum se arată:

The Utilizarea Mem coloana indică utilizarea memoriei pentru o anumită linie de cod, în timp ce Creştere coloana arată costul general contribuit de fiecare linie. The Apariția coloana definește de câte ori o linie de cod alocă sau dealoca memoria.

De exemplu, în rezultatul de mai sus, linia 11 a apărut de două ori cu un increment de memorie de 0,1 MiB (Mebibyte), crescând utilizarea memoriei la 55,4 MiB. Liniile 19 și 22 au contribuit, de asemenea, cu 0,2 MiB și, respectiv, 0,3 MiB, totalizând utilizarea memoriei la 55,9 MiB.

Găsiți profilul de memorie al unui script Python după marca temporală

De asemenea, puteți estima profilul de memorie al unui întreg script Python folosind memorie_profiler prin rularea mprof comandă în terminal, așa cum se arată:

mprof rulează script_name.py

Comanda de mai sus eșantionează scriptul specificat la fiecare 0,1 secunde și creează automat un .dat fișier în directorul actual al proiectului.

Cifrele care urmează MEM notația sunt profilurile de utilizare a memoriei ale scriptului Python la un interval de timp specific. Ultimele cifre din dreapta reprezintă marcajul de timp capturat de profiler pentru fiecare utilizare a memoriei.

De asemenea, puteți obține un grafic al profilului de memorie. Acest lucru necesită o instalare a matplotlib:

pip install matplotlib

Odată instalat, rulați mprof comanda asa:

complot mprof

Iată rezultatul în acest caz:

Rulați profilul de memorie script într-un fișier Python dedicat

Poate doriți să faceți profil pentru diferite scripturi Python. Poți sa faci asta folosind un modul Python dedicat prin intermediul lui Python subproces.

În acest fel, puteți separa profilul de memorie de baza de cod și puteți salva rezultatul graficului local:

import subproces

subprocess.run([
'mprof', 'alerga', „--include-copii”, „missing.py”
])

# salvați rezultatul graficului local
subprocess.run(['mprof', "complot", „--output=output.jpg”])

Pentru a rula profilul de memorie al scriptului, trebuie doar să rulați fișierul Python care conține codul de mai sus. Aceasta generează un grafic al profilului de memorie (output.jpg) în directorul de fișiere:

Găsiți cantitatea de memorie utilizată dintr-o execuție a funcției

Puteți găsi profilul de memorie total al unei metode sau funcție în timpul execuției folosind psutil pachet.

De exemplu, pentru a profila precedentul Manipularea Pandas DataFrame metoda din alt fișier Python:

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

# importați clasa care conține metoda dvs
din un cod.lipsă import Manipula

# instanțiază clasa
manip = Manipulare()

proces = psutil. Proces (os.getpid())
initial_memory = process.memory_info().rss

# rulați metoda țintă:
manip.manipulateData()

# obțineți informațiile despre memorie după execuție
memorie_finală = process.memory_info().rss
memorie_consumată = memorie_finală - memorie_inițială
memorie_consumată_mb = memorie_consumată / (1024 * 1024)
imprimare(f"Memorie consumată de funcția: {memory_consumed_mb:.2f} MB")

Cele de mai sus estimează profilul de memorie total al metodei în megaocteți (MB), după cum se arată:

Găsiți profilul de memorie al unei linii de cod în Jupyter Notebook

Dacă utilizați iPython în Jupyter Notebook, puteți calcula profilul de memorie al unei singure linii folosind memorie_profiler. Trebuie doar să încărcați memorie_profiler într-o singură celulă. Apoi adăugați %memit funcție magică la codul dvs. în celulele ulterioare; aceasta returnează memoria de vârf a codului și dimensiunea incrementată.

Această metodă nu funcționează cu scripturi Python obișnuite, în afară de iPython în Jupyter Notebook.

De exemplu:

De asemenea, puteți utiliza %memit funcție magică în Jypyter Notebook pentru a profila memoria unei funcții în timpul execuției:

Îmbunătățiți-vă eficiența memoriei în codul dvs. Python

Având în vedere sarcinile grele de ridicare a datelor pentru care folosim adesea Python, fiecare linie de cod are nevoie de o optimizare adecvată pentru a gestiona utilizarea memoriei. În timp ce Python are multe funcții Python încorporate, obiectele fără referință duc la pierderi de memorie.

Dacă ați renunțat la fiecare sintaxă Python care funcționează în baza de cod, fără să luați în considerare utilizarea memoriei, este posibil să doriți să priviți înapoi înainte de a merge prea departe.