Pasinaudokite šiais patarimais, kad analizuotumėte savo kodą ir sužinotumėte, kur jis yra efektyviausias arba mažiausiai efektyvus.
Kadangi Python „yra daugiau nei vienas būdas tai padaryti“, kai kurioms užduotims rasti efektyviausią atmintį taupantį metodą gali būti sudėtinga. Čia gali padėti atminties profiliuotojas. Be nutekėjimo stebėjimo, kodo atminties profilio įvertinimas padeda nustatyti, kuris kodas taupo atmintį.
Nesvarbu, ar kuriate mašininio mokymosi modelį, ar svetainę su Python, galite įvertinti scenarijų, atskirų kodo eilučių ar funkcijų atminties profilį.
Apskaičiuoti visos kodo bazės atminties profilį gali būti nepraktiška, nes tai gali labai sulėtinti programos veikimą. Geriau pasirinktinai profiliuoti funkcijas ar metodus, kurie, jūsų manymu, gali sunaudoti daugiau atminties. Bet net jei norite tai padaryti visai programai, galbūt norėsite jai tvarkyti atskirą modulį.
Python yra daug profiliavimo bibliotekų. Kai kurie iš populiariausių yra atminties_profilis, psutil, Tracemalloc, ir pympleris. Ši pamoka naudoja atminties_profilis ir psutil.
Nors psutil idealiai tinka norint įvertinti bendrą metodo ar funkcijos vykdymo atminties suvartojimą, atminties_profilis pateikia išsamesnę atminties naudojimo informaciją, įskaitant eilutes ir funkcinio lygio naudojimo tendencijas laikui bėgant.
Norėdami pradėti, įdiekite atminties_profilis į savo Python virtualią aplinką. Tai taip pat įdiegiama psutil.
pip install memory_profiler
Gaukite objekto dydį atmintyje
Atminties profiliavimą galite pradėti pirmiausia apskaičiuodami objekto, kurį ketinate naudoti atmintyje, dydį.
Šio tipo profiliavimas yra naudingas kūrimo pradžioje – bandant nustatyti, kurį objekto tipą naudoti programoje.
Pavyzdžiui, jei įstringate sprendžiant, kokius metodus naudoti užduočiai atlikti, tarkime, tinkamus Python duomenų tipą, galite gauti kiekvieno dydį baitais, kad nustatytumėte, kuris yra lengvesnis jūsų naudojimui atveju.
The sys.getsizeof Integruotas metodas praverčia čia:
importuoti sys
spausdinti (f" sąrašo dydis: {sys.getsizeof([])} baitai")
spausdinti (f" žodyno dydis: {sys.getsizeof (dict)} baitai")
spausdinti (f" langelio dydis: {sys.getsizeof(())} baitai")
spausdinti (f" nustatytas dydis: {sys.getsizeof({})} baitai")
Štai išvestis:
Taip pat galite naudoti sys.getsizeof metodas, leidžiantis palyginti įtaisytosios ir pasirinktinės funkcijos atminties dydį.
Pavyzdžiui, palyginkite šią tinkinto ilgio funkciją ciklas naudoja Python su įmontuotu len funkcija:
importuoti sys
defgetLength(kartojama):
skaičiuoti = 0dėl i in kartojamas:
skaičiuoti +=1grąžinti skaičiuoti
spausdinti (f "Įtaisyta ilgio funkcija: {sys.getsizeof (len)} baitai")
spausdinti (f "Pasirinkto ilgio funkcija: {sys.getsizeof (getLength)} baitai")
Aukščiau pateiktas kodas suteikia tokią išvestį:
Tačiau, kol sys.getsizeof matuoja objekto dydį atmintyje, atsižvelgia tik į patį objektą, o ne į jį nurodančius. Tam jums reikės išsamesnio profiliavimo metodo.
Raskite Python funkcijos atminties profilį
Išsamesnį kiekvienos funkcijos kodo eilutės atminties profilį galite gauti naudodami atminties_profilis paketą. Tai apima pridėjimą @profilis dekoratorius pagal jūsų funkciją ar metodą:
importuoti pandas
importuoti numpy
iš atminties_profilio importavimo profilioKlasė manipuliuoti:
@profilis
def manipulateData (self):
df = pandos. 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)
grįžti str (df)
manip = Manipuliuoti ()
spausdinti (manip.manipulateData())
Aukščiau pateiktas kodas pateikia išsamų kiekvienos funkcijos kodo eilutės atminties profilį, kaip parodyta:
The Atmintinės naudojimas stulpelyje nurodomas tam tikros kodo eilutės atminties naudojimas, o Prieaugis stulpelyje rodomos kiekvienos eilutės pridėtinės išlaidos. The Atsiradimas stulpelis apibrėžia, kiek kartų kodo eilutė paskirsto arba atlaisvina atmintį.
Pavyzdžiui, pirmiau pateiktame išvestyje 11 eilutė įvyko du kartus su atminties padidėjimu 0,1 MiB (Mebibaitas), todėl atminties naudojimas padidėjo iki 55,4 MiB. 19 ir 22 eilutės taip pat atitinkamai sunaudojo 0,2 MiB ir 0,3 MiB, o atminties sunaudojimas sudarė 55,9 MiB.
Raskite Python scenarijaus atminties profilį pagal laiko žymą
Taip pat galite įvertinti viso Python scenarijaus atminties profilį naudodami atminties_profilis paleisdami mprof terminalo komandą, kaip parodyta:
mprof paleiskite script_name.py
Aukščiau pateikta komanda atrenka nurodytą scenarijų kas 0,1 s ir automatiškai sukuria a .dat failą dabartiniame projekto kataloge.
Skaičiai, kurie seka po MEM žymėjimas yra Python scenarijaus atminties naudojimo profiliai tam tikru laiko intervalu. Paskutiniai skaičiai dešinėje rodo laiko žymą, kurią profiliuotojas užfiksavo kiekvienam atminties naudojimui.
Taip pat galite gauti atminties profilio brėžinį. Tam reikia įdiegti matplotlib:
pip įdiegti matplotlib
Įdiegę paleiskite mprof komandą taip:
mprof sklypas
Štai išvestis šiuo atveju:
Paleiskite scenarijaus atminties profilį tam skirtame Python faile
Galbūt norėsite sukurti skirtingų Python scenarijų profilį. Tu gali tai padaryti naudojant specialų Python modulį per Python's subprocesas.
Tokiu būdu galite atskirti atminties profiliavimo priemonę nuo kodų bazės ir išsaugoti grafiko išvestį vietoje:
importuoti subprocesas
subprocess.run([
"mprof", 'bėgti', "--įtraukti-vaikus", „trūksta.py“
])
# išsaugokite siužeto išvestį vietoje
subprocess.run(["mprof", 'siužetas', „--output=output.jpg“])
Norėdami paleisti scenarijaus atminties profilį, jums tereikia paleisti Python failą su aukščiau nurodytu kodu. Tai sukuria atminties profilio grafiką (output.jpg) failų kataloge:
Raskite funkcijos vykdymo sunaudotos atminties kiekį
Visą metodo ar funkcijos atminties profilį galite rasti vykdymo metu naudodami psutil paketą.
Pavyzdžiui, norėdami profiliuoti ankstesnįjį Pandas DataFrame manipuliavimas metodas kitame Python faile:
importuoti psutil
importuoti sys
importuoti os
sys.path.append (sys.path[0] + "/..")# importuokite klasę, kurioje yra jūsų metodas
iš kažkoks kodas.trūksta importuoti Manipuliuoti# sukurti klasę
manip = Manipuliuoti ()procesas = psutil. Procesas (os.getpid())
pradinė_atmintis = process.memory_info().rss# paleiskite tikslinį metodą:
manip.manipulateData()
# gauti atminties informaciją po vykdymo
final_memory = procesas.memory_info().rss
memory_consumed = galutinė_atmintis – pradinė_atmintis
memory_consumed_mb = atminties_sunaudota / (1024 * 1024)
spausdinti (f"Funkcijai sunaudota atmintis: {memory_consumed_mb:.2f} MB")
Aukščiau apskaičiuojamas bendras metodo atminties profilis megabaitais (MB), kaip parodyta:
Raskite kodo eilutės atminties profilį Jupyter Notepad
Jei „Jupyter Notebook“ naudojate „iPython“, galite apskaičiuoti vieno įdėklo atminties profilį naudodami atminties_profilis. Jums tereikia įkelti atminties_profilis vienoje ląstelėje. Tada pridėkite %memit magiška funkcija jūsų kodui tolesnėse ląstelėse; tai grąžina didžiausią kodo atmintį ir padidintą dydį.
Šis metodas neveikia su įprastais Python scenarijais, išskyrus iPython Jupyter Notepad.
Pavyzdžiui:
Taip pat galite naudoti %memit „Magic“ funkcija „Jypyter Notebook“, skirta funkcijos atminties profiliavimui vykdymo metu:
Pagerinkite savo Python kodo atminties efektyvumą
Atsižvelgiant į sunkias duomenų kėlimo užduotis, kurioms dažnai naudojame Python, kiekvieną kodo eilutę reikia tinkamai optimizuoti, kad būtų galima valdyti atminties naudojimą. Nors „Python“ turi daug integruotų „Python“ funkcijų, dėl nenurodytų objektų atsiranda atminties nutekėjimo.
Jei į kodų bazę išmetėte kiekvieną veikiančią Python sintaksę, neatsižvelgdami į atminties naudojimą, galbūt norėsite pažvelgti atgal, prieš pereinant per toli.