How hard is it to check for whitespace?
Guava는 공백 문자 25개를 32칸 해시 표로 판별합니다
Sergey Tselovalnikov은 Guava가 문자값의 곱셈과 32칸 표를 이용해 공백 문자를 판별하는 방식을 설명했습니다. 유니코드와 Java, Python, JavaScript가 공백으로 인정하는 문자 집합은 서로 다르며, Guava 코드는 후보 슬롯을 찾은 뒤 입력 문자와 대조합니다.
- 주제
본문
Sergey Tselovalnikov은 2026년 10월 30일 Guava의 공백 판별 코드가 단순한 문자 비교 대신 곱셈과 표 조회를 쓰는 이유를 설명했습니다. 공백 문자는 눈에 보이는 빈칸이나 ASCII 스페이스만을 뜻하지 않습니다. 유니코드의 White_Space 속성은 25개 문자를 포함하지만 언어마다 판별 기준이 다르고, 문자값을 정해진 목록과 대조하는 방식도 구현 선택에 따라 달라집니다.
예를 들어 U+00A0 NO-BREAK SPACE는 유니코드 White_Space에 들어가지만 Java의 Character.isWhitespace는 공백으로 보지 않습니다. Python의 str.isspace는 U+00A0과 유니코드 목록에 없는 U+001C도 인정합니다. JavaScript 정규식의 \s는 U+FEFF를 포함하지만 U+0085는 포함하지 않습니다. 이름에 SPACE가 들어간 U+200B ZERO WIDTH SPACE도 White_Space에는 속하지 않습니다. 유니코드 기준 자체도 바뀐 적이 있어 U+180E가 Unicode 6.3에서 목록에서 빠졌습니다.
Guava의 예시 코드는 정해진 25개 문자를 하나씩 비교하지 않고 32칸 표에서 후보 위치를 계산합니다. 문자값 c에 1682554634를 곱하고 32비트 정수 결과를 부호 없는 방향으로 27비트 이동하면 0부터 31 사이의 슬롯이 나옵니다. 이 방식은 목록에 든 문자끼리 슬롯이 겹치지 않도록 만든 완전 해시입니다. 마지막에 표의 문자와 입력 문자가 같은지 검사해 공백이 아닌 문자가 우연히 같은 슬롯을 얻어도 참으로 판정하지 않습니다.
글은 이 상수를 Guava가 고른 구체적인 이유를 밝히지 않습니다. 대신 목록의 문자들이 서로 다른 슬롯을 얻는 곱셈 상수를 브루트포스로 찾는 코드를 제시합니다. 이 구현이 다른 방식보다 얼마나 빠른지는 글에서 벤치마크하지 않았습니다. Guava의 CharMatcher는 Java char 값, 즉 기본 다국어 평면의 코드 단위를 다루며 보조 평면 문자는 서로게이트 두 개로 처리합니다.
자료: SerCe's blog / 정리·해설: Trawling
참고 자료
- guava/guava/src/com/google/common/base/CharMatcher.java at master · google/guava · GitHub — https://github.com/google/guava/blob/master/guava/src/com/google/common/base/CharMatcher.java