Dlaczego różne kolekcje Java mają różną domyślną pojemność?


11

Przyglądając się różnym konstruktorom kolekcji, pojawia się pytanie. Dlaczego ArrayList () konstruuje pustą listę o początkowej pojemności dziesięciu, a ArrayDeque () konstruuje pustą tablicę deque o początkowej pojemności wystarczającej do przechowywania 16 elementów.


Nie wiedziałem, że ma limit pojemności. Po prostu dodaję nowe elementy za pomocą add (). To zawsze działa.
Tulains Córdova

1
Myślę, że mówi o początkowym rozmiarze tablicy wewnątrz implementacji ArrayList. Jak sama nazwa wskazuje, ArrayList jest po prostu zwykłą tablicą pod okładkami i automatycznie tworzy większe tablice, gdy próbujesz dodać więcej elementów niż zawiera obecny rozmiar tablicy.
dsw88

1
Myślę, że StringBuilder to kolejny, który ma domyślną pojemność, czy to było 10 czy 16?
Ingo

@Ingo Interesujące. Nie wiedziałem nawet, że rzeczy poza kolekcjami są pomieszane z pojemnością, ale chyba ma to sens. W tym czasie nie było znacznika pojemności, więc nie wzbudziłem dużego zainteresowania innymi zastosowaniami.
Old Badman Gray,

Odpowiedzi:


17

Krótka odpowiedź

Ponieważ pojemność ArrayDeque musi być potęgą dwóch, a 16 to najmniejsza potęga dwóch, czyli co najmniej 10.


ArrayDeque musi używać wszędzie wielu operacji%, aby owinąć tablicę liniową, która udaje, że jest okrągła.

a % bmożna wyrazić tak, a & (b - 1) jakby b była potęgą dwóch. Bitowe AND jest znacznie szybsze, więc pojemność ArrayDeque jest ograniczona do potęgi dwóch. Wszystkie operacje% są wykonywane z maskowaniem bitów zamiast rzeczywistego% w implementacji.

Z tego też powodu nowszy HashMap nie używa rozmiarów tabeli liczb pierwszych, lecz potęgę dwóch , ponieważ operacja% musi być wykonywana tak często i bitowo i jest o wiele szybsza.

Więc jeśli linia bazowa to 10, to struktury, które mają moc dwóch ograniczeń, powinny użyć 16, ponieważ jest to najmniejsza potęga dwóch, co najmniej 10.


3

Nie wykluczaj możliwości, że nie ma konkretnego powodu.

Możliwe, że te dwie kolekcje zostały napisane przez różne zespoły. Obaj wybrali niewielką liczbę jako domyślną pojemność, ale pierwsza drużyna pomyślała dziesiętnie i wybiera 10, podczas gdy druga drużyna myślała binarnie i wybiera 16.


1

Odpowiedź @ Esailija jest dobra w tym konkretnym przypadku.

Mówiąc bardziej ogólnie, jest to kompromis, który zależy od wielu czynników. Podam kilka przykładów:

  • Jak zwykle używana jest struktura danych ? Struktury danych, które są używane jako bufory danych, zazwyczaj wolałyby znacznie większą pojemność niż na przykład struktury danych używane dla małych krotek.
  • Jaki domyślny rozmiar danych mieści się w linii pamięci podręcznej na docelowej platformie procesora? Może mieć to duży wpływ na wydajność, jeśli domyślnie mieści się w linii pamięci podręcznej. Wybór 10 jest domyślnie w Javie, ponieważ tablica 10 32-bitowych słów plus obciążenie tablicy / obiektu mieści się w 64-bajtowej linii pamięci podręcznej.
  • Ile cenisz przestrzeń zamiast wydajności środowiska wykonawczego ? Jeśli chcesz uzyskać lepszą wydajność środowiska wykonawczego, zwykle lepiej wstępnie przydzielić więcej miejsca, aby uniknąć późniejszych dodatkowych alokacji.

W wyniku tych kompromisów zrozumiałe jest, że różne implementacje kolekcji mogą mieć inną optymalną domyślną pojemność.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.