Skorzystaj z tych wskazówek, aby przeanalizować swój kod i odkryć, gdzie jest on najbardziej lub najmniej wydajny.
Ponieważ w Pythonie „można to zrobić na więcej niż jeden sposób”, znalezienie najbardziej efektywnego pod względem pamięci podejścia do niektórych zadań może być trudne. Tutaj może pomóc program do profilowania pamięci. Oprócz śledzenia wycieków oszacowanie profilu pamięci kodu pomaga określić, który kod jest wydajny pod względem pamięci.
Niezależnie od tego, czy tworzysz model uczenia maszynowego, czy witrynę internetową w Pythonie, możesz oszacować profil pamięci dla skryptów, poszczególnych linii kodu lub funkcji.
Oszacowanie profilu pamięci całej bazy kodu może być niepraktyczne, ponieważ może to znacznie spowolnić działanie aplikacji. Najlepiej jest selektywnie profilować funkcje lub metody, co do których podejrzewasz, że mogą zużywać więcej pamięci. Ale nawet jeśli chcesz to zrobić dla całej aplikacji, możesz poświęcić do jej obsługi izolowany moduł.
W Pythonie istnieje wiele bibliotek profilowania. Niektóre z najbardziej popularnych to
profil_pamięci, psutil, Tracemalloc, I pryszcz. Ten samouczek używa profil_pamięci I psutil.Chwila psutil jest idealny do oszacowania całkowitego zużycia pamięci przez wykonanie metody lub funkcji, profil_pamięci udostępnia bardziej szczegółowe informacje o wykorzystaniu pamięci, w tym trendy wykorzystania poszczególnych wierszy i poziomów funkcjonalnych w czasie.
Aby rozpocząć, zainstaluj profil_pamięci do wirtualnego środowiska Pythona. To również instaluje psutil.
pip zainstaluj memory_profiler
Uzyskaj rozmiar obiektu w pamięci
Możesz rozpocząć profilowanie pamięci, najpierw obliczając rozmiar obiektu, którego zamierzasz użyć w pamięci.
Ten typ profilowania jest pomocny na początku programowania — podczas próby określenia, jakiego typu obiektu użyć w programie.
Na przykład, jeśli utkniesz przy podejmowaniu decyzji, jakich metod użyć do wykonania zadania, powiedzmy, że są odpowiednie Typ danych Python, możesz uzyskać rozmiar każdego z nich w bajtach, aby określić, który jest lżejszy do użytku sprawa.
The sys.getsizeof wbudowana metoda przydaje się tutaj:
import sys
wydrukować(f"rozmiar listy: {sys.getsizeof([])} bajty")
wydrukować(f"rozmiar słownika: {sys.getsizeof (dyktowanie)} bajty")
wydrukować(f"rozmiar krotki: {sys.getsizeof(())} bajty")
wydrukować(f"ustaw rozmiar: {sys.getsizeof({})} bajtów")
Oto dane wyjściowe:
Możesz także skorzystać z tzw sys.getsizeof metoda porównywania rozmiaru pamięci wbudowanej i niestandardowej funkcji.
Na przykład porównaj tę niestandardową funkcję długości, która używa pętli for w języku Python z wbudowanym Len funkcjonować:
import sys
pokpobierzDługość(iterowalny):
liczyć = 0Do I W iterowalny:
liczyć +=1powrót liczyć
wydrukować(f"Wbudowana funkcja długości: {sys.getsizeof (dł.)} bajty")
wydrukować(f"Funkcja niestandardowej długości: {sys.getsizeof (getLength)} bajty")
Powyższy kod daje następujące dane wyjściowe:
Jednak podczas sys.getsizeof mierzy rozmiar obiektu w pamięci, uwzględnia tylko sam obiekt, a nie obiekty, które się do niego odwołują. W tym celu będziesz potrzebować bardziej szczegółowej metody profilowania.
Znajdź profil pamięci funkcji Pythona
Możesz uzyskać bardziej szczegółowy profil pamięci każdej linii kodu funkcji za pomocą profil_pamięci pakiet. Wiąże się to z dodaniem @profil dekorator do swojej funkcji lub metody:
importować pandy
importuj numpy
z profilu importu memory_profilerManipulacja klasą:
@profil
def manipuluj danymi (self):
df = pandy. Ramka danych({
'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='wypełnij', inplace=True)
powrót str (df)
manipulować = manipulować()
print(manip.manipulateData())
Powyższy kod przedstawia szczegółowy profil pamięci dla każdej linii kodu w funkcji, jak pokazano:
The Użycie pamięci kolumna wskazuje użycie pamięci dla określonej linii kodu, podczas gdy Przyrost kolumna pokazuje narzut wnoszony przez każdą linię. The Występowanie kolumna określa, ile razy linia kodu przydziela lub zwalnia pamięć.
Na przykład w powyższym wyniku wiersz 11 wystąpił dwa razy z przyrostem pamięci o 0,1 MB (Mebibajt), co zwiększyło użycie pamięci do 55,4 MiB. Wiersze 19 i 22 również przyczyniły się odpowiednio do 0,2 MiB i 0,3 MiB, co daje łączne wykorzystanie pamięci do 55,9 MiB.
Znajdź profil pamięci skryptu Pythona według znacznika czasu
Możesz także oszacować profil pamięci całego skryptu Pythona za pomocą profil_pamięci uruchamiając mprof polecenie w terminalu, jak pokazano:
mprof uruchom nazwa_skryptu.py
Powyższe polecenie próbkuje określony skrypt co 0,1 s i automatycznie tworzy plik .dat plik w bieżącym katalogu projektu.
Liczby, które następują po PAM notacja to profile użycia pamięci skryptu Pythona w określonym przedziale czasu. Ostatnie cyfry po prawej stronie reprezentują sygnaturę czasową przechwyconą przez program profilujący dla każdego użycia pamięci.
Możesz także uzyskać wykres profilu pamięci. Wymaga to instalacji matplotlib:
pip zainstaluj matplotlib
Po zainstalowaniu uruchom mprof polecenie tak:
wykres mprof
Oto dane wyjściowe w tym przypadku:
Uruchom profil pamięci skryptu w dedykowanym pliku języka Python
Możesz chcieć profilować dla różnych skryptów Pythona. Możesz to zrobić przy użyciu dedykowanego modułu Pythona przez Pythona podproces.
W ten sposób możesz oddzielić profiler pamięci od bazy kodu i zapisać dane wyjściowe wykresu lokalnie:
import podproces
podproces.uruchom([
'mprof', 'uruchomić', '--include-dzieci', „brak.py”
])
# zapisz wynik wydruku lokalnie
podproces.uruchom(['mprof', 'działka', '--wyjście=wyjście.jpg'])
Aby uruchomić profil pamięci skryptu, wystarczy uruchomić plik Pythona zawierający powyższy kod. Spowoduje to wygenerowanie wykresu profilu pamięci (wyjście.jpg) w katalogu plików:
Znajdź ilość pamięci użytej z wykonania funkcji
Możesz znaleźć całkowity profil pamięci metody lub funkcji podczas wykonywania za pomocą psutil pakiet.
Na przykład, aby profilować poprzednie Manipulacja Pandas DataFrame metoda wewnątrz innego pliku Pythona:
import psutil
import sys
import os
sys.path.append (sys.path[0] + "/..")# zaimportuj klasę zawierającą twoją metodę
z brak kodu import Manipulować# utwórz instancję klasy
manipulować = manipulować()proces = psutil. Proces (os.getpid())
początkowa_pamięć = proces.memory_info().rss# uruchom metodę docelową:
manipulacja.manipulacjadanymi()
# uzyskać informacje o pamięci po wykonaniu
final_memory = proces.memory_info().rss
zużyta_pamięć = pamięć_końcowa - pamięć_początkowa
zużyta_pamięć_mb = zużyta_pamięć / (1024 * 1024)
wydrukować(f"Pamięć zużywana przez funkcję: {memory_consumed_mb:.2F} MB")
Powyższe oszacowanie całkowitego profilu pamięci metody w megabajtach (MB), jak pokazano:
Znajdź profil pamięci linii kodu w notatniku Jupyter
Jeśli używasz iPython w Jupyter Notebook, możesz obliczyć profil pamięci jednolinijkowego za pomocą profil_pamięci. Musisz tylko załadować profil_pamięci w jednej komórce. Następnie dodaj %zapamiętaj magiczną funkcję do Twojego kodu w kolejnych komórkach; zwraca to szczytową pamięć kodu i zwiększony rozmiar.
Ta metoda nie działa ze zwykłymi skryptami Pythona oprócz iPython w Jupyter Notebook.
Na przykład:
Możesz także skorzystać z tzw %zapamiętaj funkcja magic w Jypyter Notebook do profilowania pamięci funkcji w czasie wykonywania:
Popraw wydajność pamięci w kodzie Pythona
Biorąc pod uwagę ciężkie zadania podnoszenia danych, do których często używamy Pythona, każda linia kodu wymaga odpowiedniej optymalizacji, aby zarządzać wykorzystaniem pamięci. Podczas gdy Python zawiera wiele wbudowanych funkcji Pythona, obiekty bez odwołań powodują wycieki pamięci.
Jeśli porzuciłeś każdą składnię Pythona, która działa w twoim kodzie bez uwzględnienia użycia pamięci, możesz chcieć spojrzeć wstecz, zanim posuniesz się za daleko.