다른 Java 콜렉션이 다른 기본 용량을 갖는 이유는 무엇입니까? 질문이 떠 오릅니다.

다른 컬렉션 생성자를 보면 질문이 떠 오릅니다. ArrayList ()가 초기 용량이 10 인 빈 목록을 구성하고 ArrayDeque ()가 16 개의 요소를 보유하기에 충분한 초기 용량을 가진 빈 배열 deque를 구성하는 이유는 무엇입니까?



답변

짧은 답변

ArrayDeque 용량은 2의 거듭 제곱이어야하고 16은 10의 최소 제곱입니다.


ArrayDeque는 원형 인 척하는 선형 배열을 감싸기 위해 어디에서나 많은 % 연산을 사용해야합니다.

a % ba & (b - 1) 마치 b 2의 거듭 제곱 인 것처럼 표현 될 수 있습니다 . 비트 AND는 매우 빠르므로 ArrayDeque의 용량은 2의 제곱으로 제한됩니다. 모든 % 작업은 구현에서 실제 % 대신 비트 마스킹으로 수행됩니다.

이것이 새로운 HashMap이 소수 테이블 크기를 사용하지 않고 2 의 거듭 제곱을 사용하는 이유 이기도 합니다. 왜냐하면 % 연산은 자주 그리고 비트 단위로 수행되어야하고 훨씬 빠르기 때문입니다.

따라서 기준선이 10 인 경우 두 제한의 거듭 제곱을 갖는 구조는 16을 사용해야합니다. 최소 10의 거듭 제곱은 2입니다.


답변

특별한 이유가 없을 가능성을 배제하지 마십시오.

이 두 컬렉션은 다른 팀에서 작성했을 수 있습니다. 둘 다 기본 용량으로 작은 숫자를 선택했지만 첫 번째 팀은 소수를 생각하고 10을 선택하고 두 번째 팀은 이진을 생각하고 16을 선택했습니다.


답변

@Esailija의 대답은이 특별한 경우에 좋습니다.

더 일반적으로, 그것은 많은 요인들에 의존하는 트레이드 오프입니다. 몇 가지 예를 들겠습니다.

  • 데이터 구조는 일반적으로 어떻게 사용 됩니까? 데이터 버퍼로 사용되는 데이터 구조는 일반적으로 예를 들어 작은 튜플에 사용되는 데이터 구조보다 훨씬 높은 용량을 선호합니다.
  • 대상 CPU 플랫폼 의 캐시 라인 에 맞는 기본 크기의 데이터는 무엇입니까 ? 기본값이 캐시 라인에 맞으면 성능에 큰 차이를 만들 수 있습니다. Java에서 기본적으로 10을 선택하면 10 개의 32 비트 단어 배열과 배열 / 객체 오버 헤드가 64 바이트 캐시 라인에 들어가기 때문일 수 있습니다.
  • 공간 대비 런타임 효율성의 가치는 어느 정도 입니까? 런타임 성능을 향상 시키려면 나중에 추가 재 할당을 피하기 위해 일반적으로 더 많은 공간을 미리 할당하는 것이 좋습니다.

이러한 절충의 결과로 다른 콜렉션 구현이 다른 최적의 기본 용량을 가질 수 있음을 이해할 수 있습니다.