2012-08-04 6 views
5

Viene internamente trattato come una matrice o viene trattato come un tipo completamente diverso dal CLR?Come è mappato internamente l'elenco <T>?

Sto cercando di implementare valori interi nell'elenco.

List<int> lst = new List<int>(); 
lst.Add(3); 
lst.Add(4); 

vs.

ho creare un array di numeri interi

int[] arr = new int[2]; 
arr[0] = 3; 
arr[1] = 4; 

Array restituisce risultati migliori arco di tempo. Quindi perché la gente preferisce la lista <>.

+2

Si potrebbe provare [ILSpy] (http://ilspy.net) e dare un'occhiata da soli. La ragione per avere una lista dinamicamente crescente/restringibile è che non è una dimensione fissa come "Array". –

risposta

5

List<> è un'implementazione di una struttura dati che si occupa di allocare memoria su base on-demand; consente l'inserimento e la cancellazione in qualsiasi indice ecc. Quindi è molto più conveniente di un semplice array.

Sotto il cofano, l'attuale implementazione List<> utilizza un array per l'archiviazione e l'overhead quando si eseguono operazioni di tipo array è minimo. La maggiore praticità di solito vale la piccola differenza di prestazioni (se del tutto pertinente). L'aggiunta di elementi è in genere più veloce perché l'elenco alloca blocchi di memoria e non richiede una nuova allocazione e copia su ogni aggiunta (rispetto all'array puro, in cui lo Length è sempre associato alle dimensioni in memoria).

+0

Quindi, quello che stai dicendo è, anche se trascurabile, 'Elenco <>' fornirà una risposta più lenta, in termini di _Speed_, rispetto a un 'Array'? –

+2

Ovviamente. L'elenco è un'astrazione su array e le astrazioni costano cicli CPU aggiuntivi. Tuttavia, sono d'accordo con Lucero, in condizioni normali, Elenco è più che abbastanza veloce. – Steven

+2

Il "tempo di risposta" è in genere irrilevante, la richiesta viene passata all'array sottostante dopo un controllo dei limiti (rapido ed economico). Questo è probabilmente anche sottolineato dal runtime, quindi non ha nemmeno bisogno di una chiamata aggiuntiva. – Lucero

1

Un normale elenco di accesso casuale ha in genere un array interno. L'implementazione .NET List<T> fa questo. Altre implementazioni come LinkedList<T> utilizzano catene di elementi con riferimenti anziché array. Più elenchi esotici possono usare gli alberi internamente per ordinare.

L'array interno in List<T> viene inizializzato con una lunghezza breve (4 credo) e se si tenta di aggiungere oltre i limiti massimi dell'array, viene espanso. Poiché questo può richiedere molto tempo (l'array deve essere copiato), la matrice viene raddoppiata in termini di dimensioni, vale a dire quando si aggiunge il quinto elemento, l'array interno viene ridimensionato alla lunghezza 8 e così via.

+0

Ricordo di aver letto che 'List <>' Data Structure è ottimizzata per _Speed_, mentre 'Array' DS è ottimizzato per _Memory_. Sembra che tu stia contraddicendo il fatto che 'List <>' è ottimizzato per _Speed_. (quando diciamo che viene ridimensionato e riallocato, quando si muove oltre i limiti) –

+0

Non sono d'accordo con questa distinzione. Un elenco HA una matrice internamente, quindi non è sostanzialmente diverso da un array di archiviazione. Paghi una piccola penalità di prestazioni con la lista, e per quel costo ottieni una raccolta dinamica/ridimensionabile. Quindi, in conclusione, la più grande differenza tra lista e matrice è che puoi sempre aggiungere cose ad una lista. –

+1

@bugbuster, se si desidera aggiungere un elemento a un array (in modo che "Lunghezza" aumenti, cioè non solo * cambia * un elemento esistente), è necessario ridistribuire anche l'array. L'elenco crescerà in blocchi più grandi e terrà traccia del numero di elementi utilizzati dell'array, quindi è più veloce per gli aggiunti sequenziali. – Lucero

Problemi correlati