Gebruik deze tips om uw code te analyseren en te ontdekken waar deze het meest of het minst efficiënt is.

Aangezien "er meer dan één manier is om het te doen" in Python, kan het een uitdaging zijn om de meest geheugenefficiënte benadering voor sommige taken te vinden. Dit is waar een geheugenprofiler kan helpen. Naast het opsporen van lekken, helpt het schatten van het geheugenprofiel van uw code om te bepalen welke code geheugenefficiënt is.

Of u nu een machine learning-model of een website met Python ontwikkelt, u kunt het geheugenprofiel voor scripts, individuele coderegels of functies schatten.

Het schatten van het geheugenprofiel van uw volledige codebasis kan onpraktisch zijn, omdat dit uw toepassing aanzienlijk kan vertragen. Het is het beste om selectief functies of methoden te profileren waarvan u vermoedt dat ze in plaats daarvan meer geheugen verbruiken. Maar zelfs als u dit voor uw hele toepassing wilt doen, wilt u misschien een geïsoleerde module toewijden om dit af te handelen.

Er zijn veel profileringsbibliotheken in Python. Enkele van de meest populaire zijn geheugen_profiler, psutil, Tracemalloc, En pympler. Deze zelfstudie gebruikt geheugen_profiler En psutil.

Terwijl psutil is ideaal voor het schatten van het totale geheugenverbruik van een methode of functie-uitvoering, geheugen_profiler geeft meer gedetailleerde informatie over het geheugengebruik, inclusief gebruikstrends per regel en per functieniveau in de loop van de tijd.

Installeer om te beginnen geheugen_profiler in uw virtuele Python-omgeving. Deze wordt ook geïnstalleerd psutil.

pip installeer memory_profiler

Krijg de grootte van een object in het geheugen

U kunt uw geheugenprofilering starten door eerst de grootte te berekenen van een object dat u in het geheugen wilt gebruiken.

Dit type profilering is handig aan het begin van de ontwikkeling, terwijl u probeert te bepalen welk objecttype in een programma moet worden gebruikt.

Als u bijvoorbeeld vastloopt bij het beslissen welke methoden u moet gebruiken om een ​​taak uit te voeren, bijvoorbeeld de juiste Python-gegevenstype, kunt u de grootte van elk in bytes krijgen om te bepalen welke lichter is voor uw gebruik geval.

De sys.getsizeof ingebouwde methode komt hier van pas:

importeren systeem
afdrukken(f"lijstgrootte: {sys.getsizeof([])} bytes")
afdrukken(f"woordenboek grootte: {sys.getsizeof (dict)} bytes")
afdrukken(f"tupelgrootte: {sys.getsizeof(())} bytes")
afdrukken(f "set grootte: {sys.getsizeof({})} bytes")

Dit is de uitvoer:

U kunt ook de sys.getsizeof methode om de geheugengrootte van een ingebouwde en aangepaste functie te vergelijken.

Vergelijk bijvoorbeeld deze aangepaste lengtefunctie dat gebruikt een Python for-lus met de ingebouwde lenen functie:

importeren systeem

defgetLengte(herhaalbaar):
tel = 0

voor i in herhaalbaar:
tel +=1

opbrengst graaf

afdrukken(f"Ingebouwde lengtefunctie: {sys.getsizeof (len)} bytes")
afdrukken(f"Aangepaste lengtefunctie: {sys.getsizeof (getLength)} bytes")

De bovenstaande code geeft de volgende output:

Hoewel, terwijl sys.getsizeof meet de grootte van een object in het geheugen, het houdt alleen rekening met het object zelf en niet met degenen die ernaar verwijzen. Daarvoor heb je een meer gedetailleerde profileringsmethode nodig.

Zoek het geheugenprofiel van een Python-functie

U kunt een meer gedetailleerd geheugenprofiel krijgen van elke coderegel van een functie met behulp van de geheugen_profiler pakket. Dit omvat het toevoegen van de @profiel binnenhuisarchitect voor uw functie of methode:

panda's importeren
importeer numpy
van memory_profiler importprofiel

klasse Manipuleren:
@profiel
def manipulerenData (zelf):
df = panda's. gegevensframe({
'A':[0, 3, numpy.nan, 10, 3, numpy.nan],
'B': [numpy.nan, "Panda's", numpy.nan, "Panda's", "Python", "JavaScript"],
})

df.fillna (methode='bfill', inplace=True)
df.fillna (methode='ffill', inplace=True)
retour str (df)

manip = Manipuleren()
afdrukken (manip.manipulateData())

De bovenstaande code geeft een gedetailleerd geheugenprofiel van elke regel code in de functie zoals weergegeven:

De Geheugengebruik kolom geeft het geheugengebruik voor een bepaalde coderegel aan, terwijl de Verhogen kolom toont de overhead die door elke regel wordt bijgedragen. De voorkomen kolom definieert het aantal keren dat een coderegel geheugen toewijst of vrijgeeft.

In de bovenstaande uitvoer kwam regel 11 bijvoorbeeld twee keer voor met een geheugentoename van 0,1 MiB (Mebibyte), waardoor het geheugengebruik toenam tot 55,4 MiB. Regels 19 en 22 droegen ook respectievelijk 0,2 MiB en 0,3 MiB bij, wat het totale geheugengebruik op 55,9 MiB brengt.

Zoek het geheugenprofiel van een Python-script op tijdstempel

U kunt ook het geheugenprofiel van een volledig Python-script schatten met behulp van de geheugen_profiler door het uitvoeren van de mprof commando in de terminal zoals getoond:

mprof voert script_name.py uit

De bovenstaande opdracht bemonstert het opgegeven script elke 0,1 seconde en maakt automatisch een .dat bestand in uw huidige projectdirectory.

De cijfers die volgen op de MEM notatie zijn de geheugengebruiksprofielen van het Python-script op een specifiek tijdsinterval. De laatste cijfers aan de rechterkant vertegenwoordigen het tijdstempel dat de profiler heeft vastgelegd voor elk geheugengebruik.

U kunt ook een plot van het geheugenprofiel krijgen. Dit vereist een installatie van matplotlib:

pip installeer matplotlib

Voer na installatie het mprof commando als volgt:

mprof-plot

Hier is de uitvoer in dit geval:

Voer het scriptgeheugenprofiel uit in een speciaal Python-bestand

Misschien wilt u zich profileren voor verschillende Python-scripts. Je kan dit doen met behulp van een speciale Python-module via Python subproces.

Op deze manier kunt u uw geheugenprofiler scheiden van uw codebasis en de grafiekuitvoer lokaal opslaan:

importeren subproces

subproces.run([
'mprof', 'loop', '--inclusief-kinderen', 'ontbrekende.py'
])

# sla de plotuitvoer lokaal op
subproces.run(['mprof', 'verhaallijn', '--uitvoer=uitvoer.jpg'])

Om het geheugenprofiel van het script uit te voeren, hoeft u alleen het Python-bestand met de bovenstaande code uit te voeren. Dit genereert een geheugenprofielplot (uitvoer.jpg) in de bestandsdirectory:

Zoek de hoeveelheid geheugen die wordt gebruikt bij het uitvoeren van een functie

U kunt het totale geheugenprofiel van een methode of functie tijdens uitvoering vinden met behulp van de psutil pakket.

Bijvoorbeeld om het vorige te profileren Panda's DataFrame-manipulatie methode in een ander Python-bestand:

importeren psutil
importeren systeem
importeren os
sys.pad.toevoegen (sys.pad[0] + "/..")

# importeer de klasse die uw methode bevat
van een code.ontbreekt importeren Manipuleren

# de klas instantiëren
manip = Manipuleren()

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

# voer de doelmethode uit:
manip.manipulateData()

# krijg de geheugeninformatie na uitvoering
final_memory = proces.memory_info().rss
memory_consumed = final_memory - initial_memory
memory_consumed_mb = memory_consumed / (1024 * 1024)
afdrukken(f"Geheugen verbruikt door de functie: {geheugen_verbruikt_mb:.2F} MB")

Het bovenstaande schat het totale geheugenprofiel van de methode in megabytes (MB), zoals weergegeven:

Zoek het geheugenprofiel van een coderegel in Jupyter Notebook

Als u iPython in Jupyter Notebook gebruikt, kunt u het geheugenprofiel van een oneliner berekenen met behulp van de geheugen_profiler. U hoeft alleen maar te laden geheugen_profiler in één cel. Voeg dan de % nalaten magische functie toe aan uw code in volgende cellen; dit retourneert het piekgeheugen van de code en de verhoogde grootte.

Deze methode werkt niet met reguliere Python-scripts behalve iPython in Jupyter Notebook.

Bijvoorbeeld:

U kunt ook de % nalaten magische functie in Jypyter Notebook om het geheugen van een functie tijdens runtime te profileren:

Verbeter uw geheugenefficiëntie in uw Python-code

Gezien de zware taken voor het opheffen van gegevens waarvoor we Python vaak gebruiken, moet elke coderegel voldoende worden geoptimaliseerd om het geheugengebruik te beheren. Hoewel Python veel ingebouwde Python-functies heeft, leiden objecten zonder referenties tot geheugenlekken.

Als je elke Python-syntaxis die werkt in je codebase hebt laten vallen zonder rekening te houden met geheugengebruik, wil je misschien terugkijken voordat je te ver gaat.