2012-01-09 6 views
5

Quante informazioni vengono copiate/condivise quando assegno una variabile di matrice a un'altra variabile di matrice?Quante informazioni condividono le variabili di matrice?

int[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 
int[] b = a; 
a[0] = 42; 
writefln("%s %s", a[0], b[0]); // 42 42 

A quanto pare, a e b condividono la stessa payload, perché 42 viene stampato due volte.

a ~= 10; 
writefln("%s %s", a.length, b.length); // 11 10 

Aggiunta di a non cambia b, quindi la lunghezza non sembra parte del carico utile?

b = a; 
a ~= 11; 
b ~= 42; 
writefln("%s %s", a[11], b[11]); // 11 42 

Potrebbe Un'implementazione conforme D anche stampare 42 42? Potrebbe b ~= 42 sovrascrivere l'11 all'interno di a?

Quando sono esattamente a e staccati gli uni dagli altri? D sta eseguendo qualche COW in sottofondo?

risposta

7

"Array" in D non esistono realmente.

Slices do.

fette sono solo un puntatore e una lunghezza. Quindi, quando li assegni a vicenda, il puntatore e la lunghezza vengono copiati. Se modifichi i dati di destinazione, sarà visibile in tutte le istanze delle sezioni, ma se ingrandisci una sezione, l'altra utilizzerà ancora la sua vecchia lunghezza.

Normalmente non è possibile "ridurre" la lunghezza effettiva della matrice in memoria (sebbene sia possibile ridurre la lunghezza della sezione, in modo da "vedere" meno dati), in modo da non causare problemi.

Spero che questo spieghi cosa sta succedendo.

+0

Quindi non '~ =' avere sempre la complessità lineare? Avevo l'impressione che le ripetizioni invocanti di '~ =' avrebbero funzionato meglio del quadratico ... – fredoverflow

+0

@FredOverflow: Sì, è lineare, anzi, se possibile, si aggiunge all'array originale, ma dal momento che il vecchio segmento "vede" solo la parte originale (attraverso la sua copia della lunghezza), quindi non vedrà che hai aggiunto nulla. – Mehrdad

+0

Quindi '~ =' è efficiente solo se non avviene la condivisione? Ciò significa che 'b = a' modifica in qualche modo' a' sullo sfondo, giusto? – fredoverflow

3

array variables in D are equivalent to

struct array!T{ 
    size_t length; 
    T* ptr; 

} 

(più le implementazioni per indicizzazione e tranciatura)

l'apposizione è speciale in quanto può mantenere la fetta originale e aggiunge alla fine. Questo accade solo quando o il capacity della matrice è abbastanza grande o il realloc può espandere inplace

queste ultime cose sono mantenute nel GC