2016-03-08 22 views
5

Czy konwersja z modyfikowalnego typu bytearray na niezmienny typ bytes powoduje pobranie kopii? Czy jest z tym związany jakiś koszt, czy też interpreter traktuje go po prostu jako niezmienną sekwencję bajtów, np. Odlewanie char* do const char* const w C++?Czy konwersja z bytearray na bajty powoduje pobranie kopii?

ba = bytearray() 
ba.extend("some big long string".encode('utf-8')) 

# Is this conversion free or expensive? 
write_bytes(bytes(ba)) 

to się różni między Python 3, gdzie bytes jest jego własny rodzaj i Python 2.7, gdzie bytes tylko aliasem str?

+0

Wszystkie operacje wiążą się z * pewnym * kosztem. Możesz przyjrzeć się źródłu lub użyć testów czasowych, aby sprawdzić, czy czas rośnie liniowo wraz z rozmiarem problemu (jak miało to miejsce, gdyby została wykonana kopia). –

+0

Jestem dość pewny, że konwersja 'bytearray' na' bytes' powoduje skopiowanie. Dzieje się tak dlatego, że jeśli nowe 'bytes' wskazuje na tę samą tablicę backingową co' bytearray', to nie byłoby naprawdę niezmienne. – Nayuki

+1

Należy zauważyć, że jeśli chcesz wyświetlić zawartość 'bytearray' bez tworzenia kopii, możesz _ użyć_ widoku' pamięci do tego celu. Ograniczeniem jest to, że zmiany w danych 'bytearray' zmieniają dane w' widoku pamięci' oraz że 'bytearray' nie może być zmieniany (brak" dodania "," pop ", zmiana rozmiaru przypisania plastra, itp.) Dla tak długo, jak długo istnieją eksportowane bufory (z których "widok pamięci" jest najpowszechniejszym typem utworzonym w kodzie poziomu Pythona). – ShadowRanger

Odpowiedz

11

Nowa kopia jest tworzona, bufor nie jest dzielona między bytesarray a nowym bytes obiektu, albo w Pythonie 2 lub 3.

Nie można podzielić się nim, jako przedmiot bytesarray może być nadal odwoływać gdzie indziej i zmutować wartość.

Aby uzyskać szczegółowe informacje, patrz bytesobject.c source code, gdzie buffer protocol służy do utworzenia prostej kopii danych (przez PyBuffer_ToContiguous()).

7

Martjin ma rację. Chciałem tylko poprzeć tę odpowiedź źródłem cpython.

Patrząc na źródło dla bajtów here, najpierw bytes_new nazywa, który wezwie PyBytes_FromObject, który wezwie _PyBytes_FromBuffer, która tworzy nowy obiekt bajtów i wywołuje PyBuffer_ToContiguous (zdefiniowany here). To wywołuje buffer_to_contiguous, która jest funkcją kopiowania pamięci. Komentarz do funkcji brzmi:

Skopiuj src do sąsiedniej reprezentacji. kolejność jest jedną z "C", "F" (Fortran) lub "A" (dowolna). Założenia: src ma informację PyBUF_FULL, src-> ndim> = 1, len (mem) == src-> len.

W ten sposób wywołanie bajtów z argumentem bytearray spowoduje skopiowanie danych.

Powiązane problemy