비교할 문제
Map과 Object 선택에서 확인할 질문은 동적 key lookup에서 Map과 일반 object 중 무엇을 선택할까입니다. 문자열 key만 쓰는지, 삽입 순회가 필요한지, JSON 직렬화가 필요한지와 삭제 빈도를 같게 둡니다. 결과값, 순서, 오류 처리와 부수 효과가 다르면 같은 성능 비교가 아닙니다. 먼저 두 후보가 같은 일을 하는지 작은 입력으로 확인합니다.
원인 분석과 재현
Map은 임의 key와 size·iteration에 적합하고 Object는 고정 field record에 적합하므로 lookup 속도 하나로 선택하지 않습니다.
key 100개·10만 개, hit 90%·miss 50%, 삽입·조회·삭제 workload를 나누고 prototype 없는 object도 별도 후보로 둡니다. runtime version, 운영체제, CPU와 memory 제한도 결과와 함께 기록합니다.
비교 질문은 동적 key lookup에서 Map과 일반 object 중 무엇을 선택할까입니다.
| 후보 | 유리한 조건 | 함께 치르는 비용 |
|---|---|---|
| Map | 동적 key, 잦은 삽입·삭제, size와 iterator가 필요할 때 | JSON 변환 계약을 직접 정해야 함 |
| Object.create(null) | 문자열 key와 JSON에 가까운 record | size·iteration API와 type guard가 별도 필요 |
| 일반 object | 필드가 고정된 domain record | 임의 사용자 key 저장소로 쓰면 prototype과 key coercion을 고려 |
const keys = Array.from({ length: 100_000 }, (_, i) => `key-${i}`);
const map = new Map(keys.map((key, i) => [key, i]));
const object = Object.fromEntries(keys.map((key, i) => [key, i]));
const cases = {
map() { let sum = 0; for (const key of keys) sum += map.get(key); return sum; },
object() { let sum = 0; for (const key of keys) sum += object[key]; return sum; },
};
// 삽입·조회·삭제를 한 숫자로 섞지 말고 workload별로 같은 warm-up과 반복 측정을 적용합니다.
해결 방안과 판정
warm-up과 측정 구간을 나누고 여러 번 반복합니다. 서비스 지연은 median과 p95를, 처리량 비교는 단위 시간당 완료 수와 오류율을 함께 기록합니다. CPU time, allocation, RSS·heap, GC, I/O 중 이 작업에 직접 관련된 지표만 선택합니다. 두 구조는 의미가 먼저 다릅니다. microbenchmark의 lookup 한 항목보다 serialization, key type, iteration과 memory를 포함한 실제 workload로 결정합니다.
차이가 반복 실행의 흔들림보다 작다면 더 단순하고 읽기 쉬운 구현을 선택합니다. 차이가 충분히 크더라도 실제 요청 전체의 지연과 자원 사용이 개선되는지 확인한 뒤 적용합니다.
공식 문서와 적용 범위
문서의 기본값과 동작은 version에 따라 달라질 수 있습니다. 현재 runtime·framework version, 실제 입력과 요청 흐름에서 다시 확인합니다.