2016-01-10 12 views
9

O ile rozumiem, krotki i łańcuchy są niezmienne, aby umożliwić optymalizacje, takie jak ponowne użycie pamięci, która się nie zmieni. Jednak jedna oczywista optymalizacja, polegająca na tym, że plasterki krotek odnoszą się do tej samej pamięci co oryginalna krotka, nie jest zawarta w pythonie.Skoro krotki są niezmienne, dlaczego ich krojenie tworzy kopię zamiast widoku?

wiem, że ta optymalizacja nie jest wliczone bo kiedy czas następująca funkcja, czas potrzebny idzie jak O (n^2) zamiast O (n), tak pełne kopiowanie odbywa się:

def test(n): 
    tup = tuple(range(n)) 
    for i in xrange(n): 
     tup[0:i] 

Czy jest pewne zachowanie Pythona, które się zmieni, jeśli ta optymalizacja została zaimplementowana? Czy kopiowanie ma jakąś korzyść, nawet jeśli oryginał jest niezmienny?

+8

Czasami odpowiedź brzmi: "ponieważ nikt jeszcze nie wykorzystał czasu na jej pełne wdrożenie". –

+1

Prześlij żądanie ściągnięcia :) –

+0

Może to być kompromis między zmniejszeniem ilości kopiowania, jak wskazujesz, a zmniejszeniem liczby odwołań do oryginalnej krotki, aby mogła ona zostać wcześniej zebrana. – cr3

Odpowiedz

1

Przez view, czy myślisz o czymś, co jest równoważne z tym, co robi numpy? Jestem zaznajomiony z tym, jak i dlaczego to robi.

A numpyarray to obiekt z informacjami o kształcie i dtype oraz buforze danych. Możesz zobaczyć te informacje w usłudze __array_interface__. A view to nowy obiekt typu numpy z własnym atrybutem kształtu, ale z nowym wskaźnikiem bufora danych, który wskazuje w jakimś miejscu w buforze źródłowym. Ma również flagę z napisem "Nie jestem właścicielem bufora". numpy również utrzymuje swoją własną liczbę referencyjną, więc bufor danych nie zostanie zniszczony, jeśli pierwotna (własna) tablica zostanie usunięta (i śmieci zostaną zebrane).

Takie wykorzystanie widoków może być dużym zaoszczędzeniem czasu, szczególnie w przypadku bardzo dużych tablic (pytania o błędy pamięci są powszechne w SO). Widoki pozwalają również na różne dtype, więc bufor danych może być wyświetlany w postaci 4-bajtowych liczb całkowitych lub 1-bajtowych znaków, itp.

Jak to się ma do krotek? Domyślam się, że wymagałoby to dużo dodatkowego bagażu. Krotka składa się ze stałego zestawu wskaźników obiektów - prawdopodobnie tablicy C. Widok korzystałby z tej samej tablicy, ale z własnymi znacznikami początkowymi i końcowymi (wskaźnikami i/lub długościami). A co z udostępnianiem flag? Zbieranie śmieci?

Jaka jest typowa wielkość i zastosowanie krotek? Powszechnym zastosowaniem krotek jest przekazywanie argumentów do funkcji. Domyślam się, że większość krotek w typowym biegu w Pythonie jest mała - 0, 1 lub 2 elementy. Plasterki są dozwolone, ale czy są one bardzo powszechne? Na małych krotkach lub bardzo dużych?

Czy wystąpią jakiekolwiek niezamierzone konsekwencje w tworzeniu widoków krotek plasterków (w znaczeniu liczbowym)? Rozróżnienie między widokami i kopiami jest jedną z trudniejszych rzeczy, które użytkownicy mogą zrozumieć. Ponieważ krotka ma być niezmienna - nie można zmienić wskaźników w krotce - możliwe jest, że widoki implementacyjne będą niewidoczne dla użytkowników. Ale wciąż się zastanawiam.

Najrozsądniej jest wypróbować ten pomysł w oddziale wersji PyPy - chyba, że ​​naprawdę chcesz zagłębić się w kod Cpython. Lub jako klasa niestandardowa z Cython.

Powiązane problemy