2016-03-08 15 views
5

La conversione dal tipo mutabile bytearray al tipo non modificabile bytes comporta una copia? C'è un costo associato ad esso, o l'interprete lo tratta come una sequenza di byte immutabile, come il lancio di uno char* in uno const char* const in C++?La conversione da bytearray a byte comporta una copia?

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

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

Questo differiva tra Python 3 dove bytes è il suo proprio tipo e Python 2.7 dove bytes è solo un alias per str?

+0

Tutte le operazioni comportano * un * costo. Si può guardare all'origine, oppure è possibile utilizzare i test di temporizzazione per vedere se il tempo aumenta in modo lineare con la dimensione del problema (come accadrebbe se fosse stata effettuata una copia). –

+0

Sono abbastanza sicuro che la conversione di 'bytearray' in' byte 'incorre in una copia. Questo perché se i nuovi 'byte 'puntano allo stesso array di supporto di' bytearray', allora non sarebbe veramente immutabile. – Nayuki

+1

Si noti che se si desidera una vista sul contenuto di un 'bytearray' senza fare una copia, si _can_utilizzare un' memoryview' per lo scopo. L'avvertenza è che le modifiche ai dati di 'bytearray' cambieranno i dati nel' memoryview', e che 'bytearray' non può essere ridimensionato (non' append's, 'pop's, ridimensionando le slice slice, ecc.) Per purché esistano dei buffer esportati (di cui 'memoryview' è il tipo più comune creato in codice di livello Python). – ShadowRanger

risposta

11

Viene creata una nuova copia, il buffer non è condivisa tra il bytesarray e il nuovo bytes oggetto, sia in Python 2 o 3.

non si poteva condividere, come l'oggetto bytesarray potrebbe ancora essere referenziato altrove e mutare il valore.

Per i dettagli, vedere bytesobject.c source code, in cui lo buffer protocol viene utilizzato per creare una copia diretta dei dati (tramite PyBuffer_ToContiguous()).

7

Martjin ha ragione. Volevo solo rispondere a quella risposta con la fonte cpython.

Guardando la sorgente per byte here, prima bytes_new è chiamato, che chiamerà PyBytes_FromObject, che chiamerà _PyBytes_FromBuffer, che crea un nuovo oggetto byte e chiede PyBuffer_ToContiguous (definito here). Questo chiama buffer_to_contiguous, che è una funzione di copia di memoria. Il commento per la funzione è:

Copia src in una rappresentazione contigua. l'ordine è uno tra "C", "F" (Fortran) o "A" (Qualsiasi). Presupposti: src ha informazioni PyBUF_FULL, src-> ndim> = 1, len (mem) == src-> len.

Pertanto, una chiamata ai byte con un argomento perteamray copierà i dati.