"O(1) 조회는 영원히 공짜로 주어지는 게 아니야. 너무 붐비기 전에 해시맵이 조용히 자기 몸집을 키워서 지켜내는 약속이지. 키우기를 멈추는 순간 약속도 깨져."
부하율
부하율(load factor)은 저장된 항목 수를 전체 슬롯 수로 나눈 값이야. load = entries / slots. 해시맵의 건강을 알려주는 단 하나의 숫자지. 부하가 낮으면, 이를테면 0.3쯤이면 키가 얇게 퍼져 있어서 충돌이 드물고 조회가 깔끔하게 O(1)이야. 부하가 1 쪽으로 올라가면 슬롯이 차고, 충돌이 쌓이고, 체인이 길어지거나 탐사 순서가 늘어나면서 O(1)이 조용히 O(n) 쪽으로 썩어 가. 부하율은 계기판의 바늘이야. 이거 하나만 봐도 맵이 건강한지 알 수 있어.
해법: 키우고 다시 해싱하기
해시 테이블은 탐사가 길어지기 전에 더 큰 테이블로 옮겨 가고, 기존 항목을 새 배치에 맞춰 다시 배치해. 이 작업 한 번은 O(n)이라 비싸. 하지만 여유를 충분히 두고 가끔씩만 일어나기 때문에 삽입은 분할 상환 O(1)을 유지하지. CPython dict의 정확한 사용률 임계값과 성장 폭은 버전에 따라 바뀔 수 있는 구현 세부사항이야. 2/3이라든가 정확히 두 배라든가 하는 숫자를 언어의 계약처럼 외우지는 마.
임계값은 어디쯤에 놓일까
적절한 임계값은 충돌 전략과 구현에 따라 달라져. 체이닝은 부하율이 1을 넘어도 돌아가긴 해. 체인이 길어질 뿐이지. 반면 개방 주소법은 빈 슬롯이 줄어들수록 탐사가 급격히 길어지니까 더 일찍 리사이즈해야 하고. CPython dict의 정확한 임계값과 성장 정책도 버전별 구현 세부사항이야. 기억해야 할 계약은 특정 숫자가 아니라, 빈 용량이 있어야 기대 탐사 길이가 짧게 유지된다는 사실이야.