자료구조와 알고리즘 Chapter 14 ← 13 그래프목차
제 14 장 · Dealing with Space Constraints

공간 제약 대처하기

지금까지는 줄곧 시간 복잡도—얼마나 빠른가—만 봤다. 그러나 메모리가 제한적일 때는 공간 복잡도가 중요해진다. 빅 오는 메모리도 똑같이 잰다.

공간 복잡도 보조 공간 시간 vs 공간 트레이드오프

§ 1 · 메모리도 빅 오로공간에 적용된 빅 오

메모리가 제한적인 작은 하드웨어로 작업하거나, 대량의 데이터로 큰 메모리도 빠르게 채워질 때 — 공간 복잡도(space complexity)가 중요한 요소가 된다.

흥미롭게도 컴퓨터 과학자들은 시간 복잡도와 똑같이 빅 오로 공간 복잡도를 설명한다. 시간 빅 오가 "N개 데이터에 대한 연산 단계 수"였다면, 공간 빅 오는 "N개 데이터에 대해 알고리즘이 메모리에서 소비하는 추가 데이터 요소 수"다.

문자열 배열 대문자 변환 — 버전 1 — JavaScript
function makeUpperCase(array) {
  var newArray = [];
  for(var i = 0; i < array.length; i++) {
    newArray[i] = array[i].toUpperCase();
  }
  return newArray;
}

이 함수가 끝날 때 메모리에는 원본 배열과 똑같이 N개 요소를 가진 newArray가 떠 있다. 따라서 공간 복잡도는 O(N)이다.

모션 · 두 버전의 메모리 사용 비교 단계 01 / 0
space 재생 · → 단계 · R 리셋

§ 2 · 제자리 수정두 버전의 비교

더 메모리 효율적인 버전이 있다. 새 배열을 만들지 않고, 원본 배열의 각 문자열을 제자리에서(in place) 수정한다.

대문자 변환 — 버전 2 — JavaScript
function makeUpperCase(array) {
  for(var i = 0; i < array.length; i++) {
    array[i] = array[i].toUpperCase();
  }
  return array;
}
makeUpperCase — 두 버전의 시간·공간 복잡도
버전시간 복잡도공간 복잡도
버전 1 (새 배열)O(N)O(N)
버전 2 (제자리)O(N)O(1)

두 버전 모두 시간은 O(N)이다. 그러나 버전 2는 추가 메모리를 전혀 쓰지 않으므로 공간이 O(1)이다. 이 경우 버전 2가 명백히 더 낫다.

§ 3 · 원본은 세지 않는다보조 공간

이 책에서 공간 복잡도는 보조 공간(auxiliary space)—추가로 소비하는 메모리—을 기준으로 판단한다. 원본 데이터는 세지 않는다.

공간 복잡도 — 보조 공간 기준
O(1) = 원본 외 추가 메모리 0
버전 2도 N개 요소의 입력 배열을 받지만, 원본 외에 새 메모리를 쓰지 않으므로 공간 복잡도는 O(1)이다. (원본을 포함해 계산하는 참고 자료도 있으니, 어느 쪽인지 늘 확인하라.)
핵심 시간 빅 오에서 O(1)이 "데이터 크기와 무관하게 단계 수가 일정"하다는 뜻이듯, 공간 빅 오에서 O(1)은 "데이터 크기와 무관하게 소비 메모리가 일정"하다는 뜻이다. 입력이 4개든 100개든 추가 공간은 0이다.

§ 4 · 둘을 동시에 가질 수 없을 때시간과 공간의 트레이드오프

4장의 중복 검사를 다시 보자. 두 버전이 있었다.

  • 버전 1(중첩 루프) — 추가 메모리를 쓰지 않는다. 시간 O(N²), 공간 O(1).
  • 버전 2(보조 배열) — 원본 크기의 새 배열을 만든다. 시간 O(N), 공간 O(N).
hasDuplicateValue — 시간과 공간의 거래
버전시간 복잡도공간 복잡도
버전 1 (중첩 루프)O(N²)O(1)
버전 2 (보조 배열)O(N)O(N)
함정 버전 1은 느리지만 메모리를 적게 쓰고, 버전 2는 빠르지만 메모리를 많이 쓴다. 어느 것이 정답인지는 상황에 따라 다르다. 속도가 절실하고 메모리가 넉넉하면 버전 2, 메모리가 빠듯한 하드웨어면 버전 1. 트레이드오프가 있을 땐 큰 그림을 봐야 한다.
모션 · 시간 축과 공간 축에서 본 두 버전 단계 01 / 0
space 재생 · → 단계 · R 리셋

§ 5 · 마치며이 여정이 남긴 것

이 여정에서 우리는 자료구조와 알고리즘의 분석이 코드의 속도·메모리·우아함에 극적인 영향을 미친다는 것을 배웠다.

이 책이 준 것은 교육받은 기술 결정을 내리기 위한 틀이다. 빅 오 표기법이 한 접근이 다른 것보다 낫다고 시사할 수 있지만, 하드웨어의 메모리 구성이나 언어의 내부 구현 같은 다른 요소도 작용한다. 그래서 최적화는 항상 벤치마킹 도구로 측정하는 것이 가장 좋다 — 이 책의 지식이 방향을 가리키고, 벤치마킹이 올바른 선택을 확인해준다.

복잡하고 신비로워 보이는 이 주제들은 사실 더 쉬운 개념들의 조합일 뿐이며, 모두 당신이 이해할 수 있는 범위 안에 있다. 설명이 나빠서 어려워 보인다면 겁먹지 말고 더 나은 자료를 찾아라. 자료구조와 알고리즘의 세계는 넓고 깊으며, 우리는 겨우 표면을 긁었을 뿐이다. 행운을 빈다.