Dlaczego ArrayDeque jest lepszy niż LinkedList

Staram się zrozumieć Dlaczego Java ArrayDeque jest lepsza niż Java LinkedList ponieważ obie implementują interfejs Deque.

Rzadko widzę kogoś używającego ArrayDeque w swoim kodzie. Jeśli ktoś rzuci więcej światła na sposób implementacji ArrayDeque, byłoby to pomocne.

Jeśli to zrozumiem, będę bardziej pewny siebie używając tego. Nie mogłem jasno zrozumieć implementacji JDK co do sposobu, w jaki zarządza referencjami head i tail.

Author: Jeremy S., 2011-05-28

7 answers

Linked structures są prawdopodobnie najgorszą strukturą do iteracji z pominięciem pamięci podręcznej na każdym elemencie. Poza tym zużywają dużo więcej pamięci.

Jeśli potrzebujesz dodać / usunąć oba końce, ArrayDeque jest znacznie lepszy niż lista połączona. Dostęp losowy każdy element jest również O(1) dla kolejki cyklicznej.

Jedyną lepszą operacją listy linkowanej jest usunięcie bieżącego elementu podczas iteracji.

 103
Author: bestsss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-28 17:23:34

Uważam, że głównym wąskim gardłem wydajności w LinkedList jest fakt, że za każdym razem, gdy naciskasz na jakikolwiek koniec deque, za sceną implementacja przydziela nowy węzeł listy połączonej, który zasadniczo obejmuje JVM / OS, a to jest drogie. Ponadto, za każdym razem, gdy wyskakujesz z dowolnego końca, wewnętrzne węzły LinkedList kwalifikują się do zbierania śmieci, a to więcej pracy za sceną. Ponadto, ponieważ połączone węzły listy są przydzielane tu i ówdzie, użycie pamięci podręcznej CPU nie zapewni wiele korzyści.

Jeśli może to być interesujące, mam dowód, że dodanie elementu do ArrayList lub ArrayDeque przebiega w stałym czasie amortyzowanym; patrz to .

 25
Author: coderodde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-27 11:27:48

ArrayDeque JEST NOWY w Javie 6, dlatego wiele kodu (zwłaszcza projektów, które starają się być zgodne z wcześniejszymi wersjami Javy) nie używa go.

Jest to" lepsze " w niektórych przypadkach, ponieważ nie przydzielasz węzła dla każdego elementu do wstawienia; zamiast tego wszystkie elementy są przechowywane w gigantycznej tablicy, która jest zmieniana, jeśli jest pełna.

 21
Author: Chris Jester-Young,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-28 17:18:29

Wszyscy ludzie krytykujący LinkedList, pomyślcie o każdym innym facecie, który używał List w Javie, prawdopodobnie używa ArrayList i LinkedList przez większość czasu, ponieważ byli przed Javą 6 i dlatego, że są one nauczane jako początek w większości książek.

Ale to nie znaczy, że ślepo wziąłbym stronę LinkedList Czy ArrayDeque. Jeśli chcesz wiedzieć, spójrz na poniższy benchmark wykonany przez Briana.

Konfiguracja testu uwzględnia:

  • każdy testowany obiekt jest ciągiem 500 znaków. Każdy ciąg znaków jest innym obiektem w pamięci.
  • rozmiar tablicy testowej będzie zmieniany podczas testów.
  • dla każdej kombinacji rozmiar tablicy/Kolejka-implementacja, uruchamiane jest 100 testów i obliczany jest średni czas na test.
  • każdy test polega na wypełnieniu każdej kolejki wszystkimi obiektami, a następnie ich usunięciu.
  • mierz czas w milisekundach.

Test Wynik:

  • poniżej 10 000 elementów, zarówno testy LinkedList, jak i ArrayDeque uśrednione na poziomie poniżej 1 ms.
  • gdy zbiory danych stają się większe, różnice między ArrayDeque i LinkedList średni czas testu stają się większe.
  • przy wielkości testu 9,900,000 elementów, podejście LinkedList trwało ~165% dłużej niż podejście ArrayDeque.

Wykres:

Tutaj wpisz opis obrazka

  • jeśli twoim wymaganiem jest przechowywanie 100 lub 200 elementów, to nie duża różnica w korzystaniu z jednej z kolejek.
  • jednak, jeśli rozwijasz się na urządzeniach mobilnych, możesz użyć ArrayList lub ArrayDeque z dobrym domyśleniem maksymalnej pojemności że lista może być wymagana ze względu na ścisłe ograniczenie pamięci.
  • istnieje dużo kodu, napisanego za pomocą LinkedList więc postępuj ostrożnie, decydując się na użycie ArrayDeque, zwłaszcza, że nie implementuje interfejsu List (myślę, że to wystarczająco duży powód). Może być tak, że Twoja baza kodowa intensywnie rozmawia z interfejsem listy, najprawdopodobniej i zdecydujesz się wskoczyć z ArrayDeque. Używanie go do wewnętrznych implementacji może być dobrym pomysłem...
 8
Author: pulp_fiction,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-20 17:34:47

Dostęp do elementu w ArrayDeque jest zawsze szybszy w porównaniu do LinkedList Z O(1) dla dostępu do elementów. W Linked list znalezienie ostatniego elementu zajmie O (N).

ArrayDeque jest wydajny w pamięci, ponieważ nie musisz śledzić następnego węzła w przeciwieństwie do listy połączonej.

Nawet zgodnie z dokumentacją Javy, cytowano, że

ArrayDeque jest skalowalną implementacją array interfejsu Deque. Array deques nie mają ograniczeń pojemności; rosną jako niezbędne do obsługi użytkowania. Nie są one bezpieczne dla wątków; w przypadku braku zewnętrznej synchronizacji nie obsługują współbieżnego dostępu przez wiele wątków. Elementy Null są zabronione. Klasa ta jest prawdopodobnie szybsza niż Stack, gdy jest używana jako stos, i szybsza niż LinkedList, gdy jest używana jako Kolejka.

Benchmarking z tych dwóch dowodzi, że ArrayDeque jest szybszy.

 6
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-18 07:29:26

Chociaż ArrayDeque<E> oraz LinkedList<E> czy oba wdrożone Deque<E> interfejsu, ale ArrayDeque używa w zasadzie tablicy obiektowej E[] do przechowywania elementów wewnątrz obiektu, więc zwykle używa indeksu do lokalizowania elementów głowy i ogona.

Jednym słowem, po prostu działa jak Deque( z całą metodą Deque' a), jednak używa struktury danych array. Jeśli chodzi o to, który z nich jest lepszy, zależy od tego, jak i gdzie ich używasz.

 1
Author: rekinyz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-07 19:15:30

Złożoność czasowa ArrayDeque dla dostępu do elementu to O(1), A Dla LinkList to O(N), aby uzyskać dostęp do ostatniego elementu. ArrayDeque nie jest bezpieczny wątek, więc ręczna synchronizacja jest konieczna, aby można było uzyskać do niego dostęp przez wiele wątków, a więc są one szybsze.

 -2
Author: Piyush Yawalkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-21 07:02:09