2010-08-06 12 views
5

Próbuję dostosować bazową strukturę kodu kreślenia (matplotlib), który jest aktualizowany na czasomierzu, aby przejść od używania list Pythona do danych wykresu do korzystania z numpy tablic. Chcę być w stanie jak najniżej obniżyć czas na fabułę, a ponieważ dane mogą dostać się do tysięcy punktów, szybko tracę cenny czas, jeśli nie mogę. Wiem, że do tego typu rzeczy preferowane są niewymuszone tablice, ale mam problem z ustaleniem, kiedy muszę myśleć jak programista Pythona i kiedy muszę myśleć jak programista C++, maksymalizować wydajność dostępu do pamięci.W jaki sposób Pythonic garbage collection z numpy array dołącza i usuwa?

W dokumentacji scipy.org dla funkcji append() jest zwracana kopia połączonych tablic. Czy wszystkie te kopie zbierają się prawidłowo? Na przykład:

import numpy as np 

a = np.arange(10) 
a = np.append(a,10) 
print a

To moje czytanie tego, co dzieje się na C++ - poziomie, ale gdybym wiedział, co mi mówisz, że nie będzie zadać pytanie, więc proszę mnie poprawić jeśli się 'Mylę! = P

Najpierw zostaje przydzielony blok 10 liczb całkowitych, a symbol wskazuje na początek tego bloku. Następnie zostaje przydzielony nowy blok 11 liczb całkowitych, w sumie 21 stron (84 bajty). Następnie wskaźnik jest przenoszony na początek bloku 11-int. Domyślam się, że spowodowałoby to, że algorytm zbierania śmieci zmniejszyłby liczbę odwołań bloku 10-int do zera i zwolnił go. Czy to jest poprawne? Jeśli nie, w jaki sposób upewnić się, że nie dodaję kosztów ogólnych podczas dodawania?

Nie jestem również pewien, jak poprawnie usunąć tablicę numpy, kiedy już go używam. Mam przycisk resetowania na moich działkach, który wypłukuje wszystkie dane i zaczyna od nowa. Kiedy miałem listy, robiono to przy użyciu del data[:]. Czy istnieje odpowiednia funkcja dla numpy tablic? Czy powinienem po prostu powiedzieć dane = np.array ([]) i liczyć na garbage collector, aby wykonać pracę dla mnie?

Odpowiedz

10

Punktem automatycznego zarządzania pamięcią jest to, że nie myślisz o tym. W kodzie, który napisałeś, kopie będą dobrze zebrane (prawie niemożliwe jest zmylenie zarządzania pamięcią Pythona). Jednakże, ponieważ np.append nie jest na miejscu, kod utworzy w pamięci nową tablicę (zawierającą konkatenację a i 10), a następnie zmienna a zostanie zaktualizowana tak, aby wskazywała na tę nową tablicę. Ponieważ teraz a nie wskazuje już na oryginalną tablicę, która miała wartość refcount równą 1, jej wartość refrepcji zmniejsza się do 0 i zostanie automatycznie wyczyszczona. Możesz użyć gc.collect, aby wymusić pełne oczyszczenie.

Siła Pythona nie polega na dostrajaniu dostępu do pamięci, chociaż można ją zoptymalizować. Najprawdopodobniej najlepiej posortować wstępnie alokować a (używając np. a = np.zeros(<size>)); jeśli potrzebujesz dokładniejszego strojenia, to staje się nieco owłosione. Możesz spojrzeć na Cython + Numpy tutorial dla bardzo schludnego i łatwego sposobu na integrację C z Pythonem dla zwiększenia wydajności.

Zmienne w Pythonie wskazują tylko na lokalizację, w której są przechowywane; możesz dowolną zmienną o wartości del, która zmniejszy liczbę referencyjną celu o jeden. Cel zostanie oczyszczony automatycznie po tym, jak jego licznik odniesie zero. Morałem tego jest, nie martw się o czyszczenie swojej pamięci. Nastąpi to automatycznie.

+0

Więc w zasadzie muszę się wyluzować. =) Dzięki za wyjaśnienia, pomyślałem, że tak się sprawy potoczyły, ale nie było to w 100% jasne. – pr0crastin8r

Powiązane problemy