기타 Lobsters · 1일 전

"공백 문자 하나 확인하는 게 대체 왜 이렇게 어렵냐고?" 코딩 파고들다 멘붕 온 개발자 이야기

핵심 요약
  • 구글 Guava 라이브러리에서 공백 문자를 확인하는 코드가 기괴할 정도로 복잡하게 짜여진 이유를 파헤쳤습니다.
  • 유니코드 표준 공백 25개뿐 아니라 자바, 파이썬, 자바스크립트 등 런타임마다 공백으로 인정하는 문자 기준이 제각각인 혼란이 존재합니다.
  • 구글은 25개 공백을 충돌 없이 빠르게 판별하기 위해 32비트 정수 연산과 완전 해시 함수를 사용하는 기발한 최적화를 적용했습니다.
요약 단순히 스페이스바 하나로 끝날 것 같은 '공백(whitespace)' 판별이 소프트웨어 개발에서는 상상을 초월할 정도로 복잡한 문제라는 글이 주목받고 있습니다. 글쓴이는 구글의 대표적인 자바 라이브러리인 Guava의 소스코드를 살펴보던 중, 문자가 공백인지 확인하는 메서드가 단순히 `c == ' '` 수준이 아니라 기괴할 정도로 복잡하게 짜여 있는 것을 보고 그 이유를 추적하기 시작했습니다. 먼저 '공백'에 대한 정의부터가 언어와 환경마다 제각각입니다. 유니코드 표준에서 'White_Space' 속성으로 지정된 문자는 총 25개에 달합니다. 여기에는 일반 스페이스(U+0020)뿐 아니라 표에서 숫자 너비와 맞춘 공백(FIGURE SPACE), 아주 얇은 틈을 만드는 THIN SPACE와 HAIR SPACE, 줄바꿈을 막아주는 줄 바꿈 방지 공백(NO-BREAK SPACE) 등이 포함됩니다. 심지어 오검(Ogham) 문자 공백(U+1680)은 폰트에 따라 눈에 보이는 가로 실선으로 렌더링되기도 하여 '공백은 투명하고 비어 있어야 한다'는 상식조차 깨집니다. 반대로 이름에 '스페이스'가 들어가는 ZERO WIDTH SPACE(U+200B)는 실제로는 공백이 아닌 포맷팅 문자로 분류됩니다. 더 큰 문제는 런타임마다 공백을 취급하는 기준이 완전히 다르다는 점입니다. 자바의 `Character.isWhitespace()`는 유니코드 표준과 달리 NO-BREAK SPACE(U+00A0)를 공백으로 치지 않습니다. 반면 파이썬의 `str.isspace()`는 유니코드 표준 25개에 ASCII 제어 문자인 파일 구분자(U+001C) 등을 추가해 총 29개를 공백으로 인식합니다. 자바스크립트의 정규표현식 `\s`는 유니코드 표준인 NEXT LINE(U+0085)을 제외하는 대신 ZERO WIDTH NO-BREAK SPACE(U+FEFF)를 포함합니다. 여기에 유니코드 표준 자체도 계속 개정되며 공백 목록이 바뀌기 때문에 하위 호환성을 유지해야 하는 라이브러리 개발자들에게는 큰 골칫거리입니다. 글쓴이가 발견한 구글 Guava 라이브러리는 25개의 유니코드 공백을 일일이 비교하는 비효율을 피하기 위해 정교한 '완전 해시 함수(Perfect Hash Function)' 기법을 도입했습니다. 특정 상수(1682554634)와 문자 코드를 곱한 뒤 비트 시프트(>>> 27) 연산을 거쳐 충돌 없이 32글자짜리 해시 테이블 슬롯을 바로 찾아내 일치 여부를 단 한 번의 조회로 판별하도록 설계해 성능을 극대화한 것입니다. 단순해 보이는 공백 체크 하나 뒤에 숨은 컴퓨터 공학의 깊은 디테일을 잘 보여주는 분석입니다.
Sponsored · 광고