2012-08-04 6 views
5

Czy jest wewnętrznie traktowany jako tablica lub czy CLR traktuje go zupełnie inaczej?Jak się wewnętrznie odwzorowuje lista <T>?

Próbuję wprowadzić wartości całkowite do listy.

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

vs.

tworzę tablicę liczb całkowitych

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

Array Zwraca lepsze wyniki przedziale czasowym. Dlaczego więc ludzie wolą listę <>.

+2

Możesz spróbować [ILSpy] (http://ilspy.net) i rzucić okiem. Powodem posiadania listy dynamicznie dostępnej/kurczliwej jest to, że nie ma ona ustalonego rozmiaru, jak "tablica". –

Odpowiedz

5

List<> to implementacja struktury danych, która zajmuje się przydzielaniem pamięci na żądanie; pozwala na wstawianie i usuwanie na dowolnym indeksie itd. Dlatego jest znacznie wygodniejsza niż prosta tablica.

Pod maską, obecna implementacja List<> wykorzystuje tablicę do przechowywania, a narzuty podczas wykonywania operacji podobnych do tablicowych są minimalne. Dodatkowa wygoda jest zazwyczaj warta niewielkiej (jeśli w ogóle istotnej) różnicy w wydajności. Dodawanie elementów jest zwykle szybsze, ponieważ lista przydziela porcje pamięci i nie wymaga nowej alokacji i kopiowania przy każdym dodaniu (w porównaniu do czystej tablicy, gdzie Length jest zawsze związany z rozmiarem w pamięci).

+0

Więc, co mówisz, choć pomijalne, 'List <>' zapewni wolniejszą odpowiedź, w kategoriach _Speed_, niż 'Tablica'? –

+2

Oczywiście. Lista jest abstrakcją ponad tablicą, a abstrakcje kosztują dodatkowe cykle procesora. Howevrr, zgadzam się z Lucero, w normalnych warunkach, List jest więcej niż wystarczająco szybki. – Steven

+2

"Czas odpowiedzi" jest zwykle nieistotny, żądanie przechodzi do podstawowej tablicy po (szybkim i tanim) sprawdzeniu granic. Prawdopodobnie jest to nawet zainicjowane przez środowisko wykonawcze, więc nie potrzebuje nawet dodatkowego połączenia. – Lucero

1

Normalna lista dostępu losowego zwykle ma wewnętrzną tablicę. Implementacja .NET List<T> to robi. Inne implementacje, takie jak LinkedList<T>, używają łańcuchów elementów z odniesieniami zamiast tablic. Bardziej egzotyczne listy mogą wykorzystywać wewnętrzne drzewa do zamawiania.

Wewnętrzna tablica w List<T> została zainicjowana krótką (4 myślę), a jeśli spróbujesz dodać poza maksymalnymi granicami tablicy, zostanie ona rozszerzona. Ponieważ może to być czasochłonne (tablica musi zostać skopiowana), tablica ma podwójny rozmiar, tj. Po dodaniu piątego elementu rozmiar wewnętrznej tablicy zostanie zmieniony na długość 8 i tak dalej.

+0

Pamiętam czytanie, że 'List <>' Struktura danych jest zoptymalizowana dla _Speed_, natomiast 'Array' DS jest zoptymalizowany dla _Memory_. Wydaje się, że zaprzeczasz temu, że 'List <>' jest zoptymalizowany dla _Speed_. (kiedy mówimy, że zmienia rozmiar i jest ponownie przydzielany, gdy wychodzimy poza granice) –

+0

Nie zgadzam się z tym rozróżnieniem. Lista ma wewnętrzną tablicę, więc zasadniczo nie różni się od macierzy pod względem pamięci masowej. Z listą płacisz niewielką karę za wykonanie, a za ten koszt otrzymujesz kolekcję dynamiczną/zmienną. Podsumowując, największą różnicą między listą a tablicą jest to, że zawsze możesz DODAĆ rzeczy do listy. –

+1

@bugbuster, jeśli chcesz dodać element do tablicy (aby zwiększyć "Długość", to znaczy nie tylko * zmienić * istniejący element), musisz również ponownie przydzielić tablicę. Lista będzie rosła w większych porcjach i będzie śledzić liczbę używanych elementów tablicy, dzięki czemu jest szybsza w przypadku dodawania sekwencyjnego. – Lucero