2011-12-11 21 views

risposta

10

Praticamente la stessa quantità di memoria (tecnicamente, lo List probabilmente ne consumerà di più perché è sovra-allocato in modo che possa crescere più facilmente).

Le raccolte generiche in .NET non hanno bisogno di inscatolare gli oggetti in loro possesso, il che sarebbe un enorme spreco di memoria e prestazioni.

+3

Si vuole dire che Elenco <> è un array quando si tratta di implementazione? –

+2

@Daniel: Sì, una matrice espandibile. – sepp2k

+1

@ DanielMošmondor: [Sì] (http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx): * La classe List (Of T) è l'equivalente generico della classe ArrayList. Implementa l'interfaccia generica IList (Of T) usando un array le cui dimensioni sono aumentate dinamicamente come richiesto. * – Jon

1

Lo chiedo perché, per quanto ne so, .NET non ha una specializzazione di modelli (generici).

.Net non ha la specializzazione del modello nel senso che tu (come programmatore) puoi fornire codice diverso a seconda degli argomenti del tipo. Ma il compilatore può ancora (e fa) produrre un codice diverso per i tipi di valore rispetto al tipo di riferimento, ad esempio (a differenza di Java) i tipi di valore non sono racchiusi quando vengono messi in un contenitore generico. Sono memorizzati in modo efficiente.

5

Il List<T> possiede un array T[]. Utilizza una strategia di crescita esponenziale per questo array, quindi un elenco con elementi n di solito dispone di un array di supporto con dimensioni maggiori di n. Anche gli array più piccoli devono essere raccolti dai rifiuti, il che può essere fastidioso se sono abbastanza grandi da essere sul LoH.

Tuttavia, è possibile evitare ciò specificando una capacità manualmente, ad esempio come parametro costruttore. Quindi verrà assegnato un singolo array con la capacità desiderata, in modo da evitare entrambi i problemi di cui sopra.

Inoltre List<T> ha un piccolo overhead O (1) per l'oggetto elenco stesso.


Tuttavia, non è previsto un sovraccarico per elemento quando si utilizzano i generici. Il runtime crea una versione specializzata per ogni tipo di valore che si passa. Non si verifica la boxe degli elementi.

Ma non è possibile utilizzare la specializzazione del modello di stile C++, in cui si sovraccarica in modo efficace l'implementazione per determinati parametri di tipo. Tutte le istanze generiche condividono lo stesso codice C#.

ovvero non esiste un codice IL specializzato, ma ogni tipo di valore ottiene un'implementazione di codice macchina specializzata basata sullo stesso codice sorgente.

1

L'utilizzo di elenchi è più pratico rispetto all'utilizzo di matrici semplici. La chiave per le prestazioni e il consumo di memoria è la capacità di un elenco. Di default inizia con un valore di 4 e aumenta a 8, 16, 32, 64, ... ogni volta che gli elementi della lista raggiungono la capacità definita. Ogni incremento è tradotto in una riallocazione interna e in Array.Copy. Quindi se hai una lista con 1000 articoli e ti aspetti 100 articoli in un giorno, puoi istanziare l'elenco con una capacità di 1200 (margine di errore nella previsione 100%). In questo modo eviterai la riassegnazione di 2000 articoli ogni volta che aggiungi l'elemento 10001 e, naturalmente, le continue ridistribuzioni e Array.Copy per riempirlo con i 1000 elementi esistenti.