Niektóre stwierdzenia tutaj są mylące lub nawet błędne, szczególnie idea niezmienności. Wektor w Scali przypomina coś w rodzaju ArrayList. Zarówno lista, jak i wektor są niezmiennymi, trwałymi (tzn. „Tanio, aby otrzymać zmodyfikowaną kopię”) strukturami danych. Nie ma rozsądnego domyślnego wyboru, ponieważ może to być zmienne struktury danych, ale zależy to raczej od tego, co robi twój algorytm. Lista jest pojedynczo połączoną listą, podczas gdy Vector jest liczbą całkowitą 32, tj. Jest rodzajem drzewa wyszukiwania z węzłami stopnia 32. Korzystając z tej struktury, Vector może zapewnić dość popularne operacje dość szybko, tj. W O (log_32 ( n)). Działa to w przypadku prepend, append, update, random access, dekompozycji w głowie / ogonie. Iteracja w kolejności sekwencyjnej jest liniowa. Z drugiej strony lista zapewnia po prostu liniową iterację i stały czas wyprzedzania, rozkład głowy / ogona.
Może to wyglądać tak, jakby Vector był dobrym zamiennikiem listy w prawie wszystkich przypadkach, ale poprzedzanie, dekompozycja i iteracja są często kluczowymi operacjami na sekwencjach w programie funkcjonalnym, a stałe tych operacji są (znacznie) wyższe dla wektora z powodu do bardziej skomplikowanej struktury. Zrobiłem kilka pomiarów, więc iteracja jest około dwa razy szybsza dla list, prepend jest około 100 razy szybszy na listach, rozkład głowy / ogona jest około 10 razy szybszy na listach, a generowanie z ruchu jest około 2 razy szybsze dla wektorów. (Jest tak prawdopodobnie dlatego, że Vector może przydzielić tablice 32 elementów jednocześnie, gdy budujesz go za pomocą konstruktora zamiast dodawania lub dodawania elementów jeden po drugim).
Więc jakiej struktury danych powinniśmy użyć? Zasadniczo istnieją cztery typowe przypadki:
- Musimy tylko transformować sekwencje za pomocą operacji takich jak mapowanie, filtrowanie, składanie itp.: W zasadzie nie ma to znaczenia, powinniśmy zaprogramować nasz algorytm ogólnie, a może nawet skorzystać z akceptacji sekwencji równoległych. W przypadku operacji sekwencyjnych lista jest prawdopodobnie nieco szybsza. Ale powinieneś przeprowadzić analizę porównawczą, jeśli musisz zoptymalizować.
- Potrzebujemy dużo losowego dostępu i różnych aktualizacji, więc powinniśmy użyć wektora, lista będzie zbyt powolna.
- Działamy na listach w klasyczny funkcjonalny sposób, budując je przez poprzedzanie i iterację przez rekurencyjny rozkład: lista użycia, wektor będzie wolniejszy o współczynnik 10-100 lub więcej.
- Mamy algorytm krytyczny pod względem wydajności, który jest w zasadzie konieczny i zapewnia losowy dostęp do listy, coś w rodzaju szybkiego sortowania: użyj imperatywnej struktury danych, np. ArrayBuffer, lokalnie i kopiuj dane zi do niego.
List<String> l = new ArrayList<String>()
blogi Scala. Czy wierzysz, że wszyscy używają Listu, aby uzyskać trwałą kolekcjonerską dobroć - ale czy Vector jest wystarczający do ogólnego zastosowania, że powinniśmy go używać zamiast Listu?