2012-06-12 15 views
16

Mam bardzo duży skrypt Pythona, 200K, który chciałbym użyć jak najmniejszej ilości pamięci. Wygląda to mniej więcej tak:Jak zmniejszyć wykorzystanie pamięci skryptów Python

# a lot of data structures 
r = [34, 78, 43, 12, 99] 

# a lot of functions that I use all the time 
def func1(word): 
    return len(word) + 2 

# a lot of functions that I rarely use 
def func1(word): 
    return len(word) + 2 


# my main loop 
while 1: 
    # lots of code 
    # calls functions 

Jeśli mogę umieścić funkcje, które rzadko korzystają z modułu, a następnie zaimportować je dynamicznie tylko w razie potrzeby, nie ma dostępu do danych. To tyle, ile dostałem.

Jestem nowy w Pythonie.

Czy ktoś może umieścić mnie na właściwej ścieżce? Jak mogę złamać ten duży skrypt, aby zużywał mniej pamięci? Czy warto umieszczać rzadko używany kod w modułach i dzwonić tylko w razie potrzeby?

+4

Czy jesteś pewien, że używa * zbyt dużej * pamięci? – eumiro

+5

Czy profilowałeś swój kod? – Daenyth

+1

Pamiętaj, że "Przedwczesna optymalizacja jest źródłem wszelkiego zła". – Amr

Odpowiedz

2

Przenoszenie funkcji nie zmieni użycia pamięci. Natychmiast po zaimportowaniu tego innego modułu zostanie zdefiniowane wszystkie funkcje w module. Ale funkcje nie zajmują dużo pamięci. Czy są one niezwykle powtarzalne, być może możesz mieć mniej kodu poprzez refaktoryzację funkcji?

@ Eumiro ma pytanie: czy jesteś pewien, że twój skrypt używa zbyt dużo pamięci? Ile pamięci używa i dlaczego jest za dużo?

22

Organzing:

Twój skrypt python wydaje się rzeczywiście być ogromna, być może należy rozważyć reorganizację pierwszy kod, aby podzielić się na kilka modules or packages . Prawdopodobnie ułatwi to profilowanie kodu i zadania optymalizacyjne.

Możesz zajrzeć tam:

i ewentualnie:

Optymalizacja:

Jest wiele rzeczy, które można zrobić w celu optymalizacji kodu ...

Na przykład, w odniesieniu do swoich struktur danych ... Jeśli w dużym stopniu korzystasz z list lub list ze zrozumieniem, możesz spróbować dowiedzieć się, gdzie naprawdę potrzebujesz list, i gdzie mogą one zostać zastąpione przez niezmienną strukturę danych takie jak krotki lub obiekty "ulotne", "leniwe" kontenery, takie jak wyrażenia generatora.

Patrz:

Na tych stronach można znaleźć użyteczne informacje i wskazówki:

Ponadto, należy badać swoje sposoby robienia rzeczy i zastanawiam się, czy istnieje sposób, aby to zrobić mniej zachłannie, sposób, że lepiej zrób to w Pythonie (znajdziesz kilka wskazówek w tagu pythonic) ... Jest to szczególnie prawdziwe w Pythonie, ponieważ w Pythonie często jest jeden "oczywisty" sposób (i tylko jeden), aby robić rzeczy, które są lepsze niż inne s (patrz The Zen of Python), o którym mówi się, że jest to pythonic. Nie jest to szczególnie związane z kształtem twojego kodu, ale także - i przede wszystkim - z występami. W przeciwieństwie do wielu języków, które promują ideę, że powinno być wiele sposobów robienia czegokolwiek, Python woli skupić się tylko na najlepszej drodze. Oczywistym jest, że jest wiele sposobów na zrobienie czegoś, ale często jeden z nich jest lepszy.

Teraz powinieneś również sprawdzić, czy używasz najlepszych metod robienia rzeczy, ponieważ pythonicality nie zorganizuje dla ciebie algorytmów.

Ale nareszcie bardzo zależy od kodu, na który trudno odpowiedzieć, nie widząc go.

Pamiętaj też, aby uwzględnić komentarze zgłoszone przez eumiro i Amr.

+0

Czy znasz jakiś dobry sposób na określenie ilości pamięci jaką zajmuje fragment kodu Pythona? Łatwo jest użyć 'timeit' do porównań szybkości, więc szukam czegoś, co pozwoli mi określić/scharakteryzować zużycie pamięci. Ciekawe, czy jest coś tak prostego. – Levon

+2

[memory_profiler] (http://pypi.python.org/pypi/memory_profiler) jest całkiem przydatny, łatwy w użyciu do szybkiego debugowania. Teraz możesz spróbować [meliae] (https://code.launchpad.net/meliae) ([krok po kroku] (http://jam-bazaar.blogspot.ie/2010/08/step- by-step-meliae.html)) lub [heapy] (http://guppy-pe.sourceforge.net/#Heapy) w celu uzyskania pełniejszych rozwiązań. Dobra dyskusja [tutaj] (http://stackoverflow.com/questions/110259/python-memory-profiler) i niektóre ciekawe metody szacowania [tutaj] (http://stackoverflow.com/questions/563840/how-can-i -check-the-memory-use-of-objects-in-ipython) – cedbeu

+0

Myślę, że bardziej szukasz czegoś takiego jak moduł [memory_profiler] (http://pypi.python.org/pypi/memory_profiler), o którym wspomniałem, chociaż. – cedbeu

3

Porady dotyczące wyrażeń generatora i korzystania z modułów są dobre. Przedwczesna optymalizacja powoduje problemy, ale powinieneś zawsze poświęcić kilka minut na zastanowienie się nad swoim projektem, zanim usiądziesz do napisania kodu. Szczególnie jeśli ten kod ma być ponownie użyty.

Nawiasem mówiąc, wspomniałeś, że masz wiele struktur danych zdefiniowanych w górnej części skryptu, co oznacza, że ​​wszystkie są załadowane do pamięci na początku. Jeśli jest to bardzo duży zbiór danych, rozważ przeniesienie określonych zestawów danych do oddzielnych plików i załadowanie go tylko w razie potrzeby. (używając modułu csv lub numpy.loadtxt(), itp.)

Oddzielenie od korzystania z mniejszej ilości pamięci, patrz także na sposoby efektywniejszego wykorzystania pamięci. Na przykład w przypadku dużych zbiorów danych liczbowych numpy tablice są sposobem przechowywania informacji, które zapewnią lepszą wydajność w obliczeniach. Istnieje pewna nieco przestarzała porada pod adresem http://wiki.python.org/moin/PythonSpeed/PerformanceTips

Powiązane problemy