Izmantojiet šos padomus, lai analizētu savu kodu un uzzinātu, kur tas ir visefektīvākais vai neefektīvākais.

Tā kā Python “ir vairāk nekā viens veids, kā to izdarīt”, dažiem uzdevumiem var būt grūti atrast visefektīvāko pieeju, kas patērē atmiņu. Šeit var palīdzēt atmiņas profilētājs. Koda atmiņas profila noteikšana ne tikai izseko noplūdes, bet arī palīdz noteikt, kurš kods ir atmiņu taupošs.

Neatkarīgi no tā, vai izstrādājat mašīnmācīšanās modeli vai vietni ar Python, varat aprēķināt skriptu, atsevišķu koda rindu vai funkciju atmiņas profilu.

Visa koda bāzes atmiņas profila aplēse var būt nepraktiska, jo tas var ievērojami palēnināt lietojumprogrammas darbību. Vislabāk ir selektīvi profilēt funkcijas vai metodes, kuras, jūsuprāt, varētu patērē vairāk atmiņas. Bet pat tad, ja vēlaties to darīt visai lietojumprogrammai, iespējams, vēlēsities tās apstrādei veltīt atsevišķu moduli.

Python ir daudz profilēšanas bibliotēku. Daži no populārākajiem ir atmiņas_profils, psutil, Tracemalloc, un pympler. Šī apmācība izmanto atmiņas_profils un psutil.

instagram viewer

Kamēr psutil ir ideāli piemērots metodes vai funkcijas izpildes kopējā atmiņas patēriņa novērtēšanai, atmiņas_profils sniedz detalizētāku informāciju par atmiņas lietojumu, tostarp pa rindiņām un funkcionālā līmeņa lietojuma tendences laika gaitā.

Lai sāktu, instalējiet atmiņas_profils savā Python virtuālajā vidē. Tas arī instalē psutil.

pip install memory_profiler

Iegūstiet atmiņā esošā objekta izmēru

Varat sākt atmiņas profilēšanu, vispirms aprēķinot objekta izmēru, kuru plānojat izmantot atmiņā.

Šis profilēšanas veids ir noderīgs izstrādes sākumā, mēģinot noteikt, kuru objekta veidu programmā izmantot.

Piemēram, ja esat iestrēdzis, izlemjot, kuras metodes izmantot uzdevuma veikšanai, teiksim, atbilstošās Python datu tipu, varat iegūt katra lielumu baitos, lai noteiktu, kurš ir vieglāks jūsu lietošanai lietu.

The sys.getsizeof Šeit noder iebūvētā metode:

imports sys
drukāt (f" saraksta izmērs: {sys.getsizeof([])} baiti")
drukāt (f" vārdnīcas izmērs: {sys.getsizeof (dict)} baiti")
drukāt (f" kopas izmērs: {sys.getsizeof(())} baiti")
drukāt (f" iestatītais izmērs: {sys.getsizeof({})} baiti")

Šeit ir izvade:

Varat arī izmantot sys.getsizeof metode, lai salīdzinātu iebūvētās un pielāgotās funkcijas atmiņas lielumu.

Piemēram, salīdziniet šo pielāgotā garuma funkciju izmanto Python cilpai ar iebūvēto len funkcija:

imports sys

defgetLength(atkārtojams):
skaits = 0

priekš i iekšā atkārtojams:
skaits +=1

atgriezties skaitīt

drukāt (f"Iebūvētā garuma funkcija: {sys.getsizeof (len)} baiti")
drukāt (f"Pielāgota garuma funkcija: {sys.getsizeof (getLength)} baiti")

Iepriekš minētais kods dod šādu izvadi:

Tomēr, kamēr sys.getsizeof mēra objekta izmēru atmiņā, tas ņem vērā tikai pašu objektu, nevis tos, kas uz to atsaucas. Šim nolūkam jums būs nepieciešama detalizētāka profilēšanas metode.

Atrodiet Python funkcijas atmiņas profilu

Varat iegūt detalizētāku atmiņas profilu katrai funkcijas koda rindai, izmantojot atmiņas_profils iepakojums. Tas ietver pievienošanu @profils dekorētājs jūsu funkcijai vai metodei:

importēt pandas
importa numpy
no memory_profiler importēšanas profila

klase Manipulēt:
@profils
def manipulateData (self):
df = pandas. 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='ffill', inplace=true)
atgriešanās str (df)

manip = Manipulēt ()
drukāt (manip.manipulateData())

Iepriekš minētais kods sniedz detalizētu atmiņas profilu katrai koda rindai funkcijā, kā parādīts attēlā:

The Atmiņas lietojums kolonna norāda atmiņas lietojumu konkrētai koda rindai, savukārt Pieaugums kolonna parāda katras rindas pieskaitāmās izmaksas. The Notikums kolonna definē, cik reižu koda rinda piešķir vai atdala atmiņu.

Piemēram, iepriekš minētajā izvadā 11. rindiņa notika divas reizes ar atmiņas pieaugumu par 0,1 MiB (Mebibaits), palielinot atmiņas lietojumu līdz 55,4 MiB. 19. un 22. līnija arī nodrošināja attiecīgi 0,2 MiB un 0,3 MiB, kopā atmiņas lietojumu sasniedzot 55,9 MiB.

Atrodiet Python skripta atmiņas profilu pēc laikspiedola

Varat arī novērtēt visa Python skripta atmiņas profilu, izmantojot atmiņas_profils palaižot mprof komanda terminālī, kā parādīts:

mprof palaist script_name.py

Iepriekš minētā komanda ik pēc 0,1 s ņem norādītā skripta paraugus un automātiski izveido a .dat failu pašreizējā projekta direktorijā.

Skaitļi, kas seko MEM apzīmējumi ir Python skripta atmiņas lietojuma profili noteiktā laika intervālā. Pēdējie skaitļi pa labi apzīmē laika zīmogu, ko profilētājs ir tvēris katram atmiņas lietojumam.

Varat arī iegūt atmiņas profila grafiku. Tam nepieciešama instalēšana matplotlib:

pip instalēt matplotlib

Pēc instalēšanas palaidiet mprof komanda šādi:

mprof gabals

Šeit ir izvade šajā gadījumā:

Palaidiet skripta atmiņas profilu īpašā Python failā

Iespējams, vēlēsities izveidot profilu dažādiem Python skriptiem. Tu to vari izdarīt izmantojot īpašu Python moduli caur Python's apakšprocess.

Tādā veidā jūs varat atdalīt atmiņas profilētāju no koda bāzes un saglabāt diagrammas izvadi lokāli:

imports apakšprocess

subprocess.run([
'mprof', 'skriet', "--iekļaut-bērnus", 'missing.py'
])

# saglabājiet sižeta izvadi lokāli
subprocess.run(['mprof', 'sižets', '--output=output.jpg'])

Lai palaistu skripta atmiņas profilu, jums ir jāpalaiž tikai Python fails, kas satur iepriekš minēto kodu. Tas ģenerē atmiņas profila diagrammu (izvade.jpg) failu direktorijā:

Atrodiet funkcijas izpildei izmantotās atmiņas apjomu

Metodes vai funkcijas kopējo atmiņas profilu var atrast izpildes laikā, izmantojot psutil iepakojums.

Piemēram, lai profilētu iepriekšējo Pandas DataFrame manipulācijas metode citā Python failā:

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

# importējiet klasi, kurā ir jūsu metode
no kaut kāds kods.trūkst imports Manipulēt

# izveidot klasi
manip = Manipulēt ()

process = psutil. Process (os.getpid())
sākotnējā_atmiņa = process.memory_info().rss

# palaist mērķa metodi:
manip.manipulateData()

# iegūt atmiņas informāciju pēc izpildes
final_memory = process.memory_info().rss
memory_consumed = galīgā_atmiņa — sākotnējā_atmiņa
memory_consumed_mb = memory_consumed / (1024 * 1024)
drukāt (f"Funkcija patērētā atmiņa: {memory_consumed_mb:.2f} MB")

Iepriekš minētais metodes kopējais atmiņas profils tiek novērtēts megabaitos (MB), kā parādīts attēlā:

Atrodiet koda rindas atmiņas profilu Jupyter piezīmjdatorā

Ja Jupyter piezīmjdatorā izmantojat iPython, varat aprēķināt viena oderējuma atmiņas profilu, izmantojot atmiņas_profils. Vajag tikai ielādēt atmiņas_profils vienā šūnā. Pēc tam pievienojiet %memit burvju funkcija jūsu kodam nākamajās šūnās; tas atgriež koda maksimālo atmiņu un palielinātu izmēru.

Šī metode nedarbojas ar parastajiem Python skriptiem, izņemot iPython Jupyter piezīmjdatorā.

Piemēram:

Varat arī izmantot %memit burvju funkcija Jypyter Notebook, lai profilētu funkcijas atmiņu izpildes laikā:

Uzlabojiet atmiņas efektivitāti savā Python kodā

Ņemot vērā lieljaudas datu pacelšanas uzdevumus, kuriem mēs bieži izmantojam Python, katrai koda rindiņai ir nepieciešama atbilstoša optimizācija, lai pārvaldītu atmiņas lietojumu. Lai gan Python ir daudzas iebūvētas Python funkcijas, objekti, kuriem nav atsauces, izraisa atmiņas noplūdes.

Ja esat atmetis katru Python sintaksi, kas darbojas jūsu koda bāzē, neņemot vērā atmiņas lietojumu, iespējams, vēlēsities atskatīties, pirms dodaties pārāk tālu.