기타 Lobsters · 2026-10-22

enum 문자열 변환 메모리 극한으로 줄이는 법 (근사치+보정 테이블)

핵심 요약
  • 열거형(enum)을 문자열로 변환할 때 포인터 배열이나 오프셋 테이블이 차지하는 메모리를 줄이기 위한 최적화 기법이 소개되었습니다.
  • 선형 근사식(x * 17)으로 대략적인 위치를 잡고 오차 범위(-9~+10)만 1바이트 크기(int8_t)의 보정 테이블로 관리하여 용량을 대폭 줄였습니다.
  • 빠르지만 불완전한 근사 연산에 작은 보정 테이블을 결합하는 방식은 컴파일러가 놓칠 수 있는 유용한 메모리 절약 패턴입니다.
요약 열거형(enum) 값을 문자열로 변환하는 함수는 프로그래밍에서 매우 흔하게 작성되지만, 단순한 switch 문으로 구현할 경우 컴파일 최적화 수준(-O0, -O1 등)에 따라 매우 비효율적인 어셈블리 코드가 생성될 수 있습니다. 현대 gcc 컴파일러는 -O2 이상의 최적화 옵션에서 이를 문자열 포인터 배열을 참조하는 형태로 자동 재작성해주지만, 포인터 배열 자체의 크기와 재배치(relocation) 엔트리가 차지하는 메모리는 여전히 부담이 될 수 있습니다. 작성자는 이러한 메모리 사용량을 줄이기 위해 먼저 모든 문자열을 널 문자(\0)로 구분하여 하나의 연속된 메모리 공간에 합치고, 각 문자열의 상대적 오프셋을 저장하는 배열(uint16_t offsets[]) 방식을 적용했습니다. 상대 오프셋은 전체 메모리 주소를 담는 포인터보다 훨씬 작은 용량을 차지하기 때문입니다. 여기서 더 나아가 작성자는 수학적 근사치와 보정 테이블을 활용하는 최적화 기법을 제안했습니다. 오프셋이 0에서 시작해 382까지 증가하는 선형적 경향을 띤다는 점에 착안하여, 382/22의 반올림 값인 17을 곱하는 1차 선형 근사식(x * 17)을 세웠습니다. 실제 오프셋 값과 근사치(x * 17)의 차이를 계산해보니 그 오차가 항상 -9에서 +10 사이라는 좁은 범위에 들어맞았습니다. 그 결과, 2바이트 크기(uint16_t)의 오프셋 테이블 대신 1바이트 크기(int8_t)의 보정치(correction) 테이블만 유지하고도 `(x * 17) + corrections[x]` 연산을 통해 정확한 문자열 주소를 복원할 수 있게 되었습니다. 작성자는 빠르지만 약간 부정확한 근사 연산에 작은 보정 테이블을 결합하는 방식이 메모리를 획기적으로 줄이는 유용한 최적화 패턴이며, 컴파일러 개발자들에게도 여전히 놓치고 있는 최적화 영역이 있음을 상기시켜 준다고 설명했습니다.
Sponsored · 광고