백트래킹(Backtracking) 방식의 함정: 정규 표현식(Regular Expression) 성능 저하의 주범
백트래킹(Backtracking) 방식의 정규 표현식 엔진은 특정 패턴에서 지수적 시간 복잡도(Exponential Time Complexity)를 보이며 성능 저하를 유발함.
톰슨 NFA(Thompson NFA) 기반 엔진은 이러한 문제를 해결하며, 선형 시간 복잡도(Linear Time Complexity)를 보장하여 빠른 성능을 제공함.
Java, Perl, PHP, Python, Ruby 등 많은 언어에서 백트래킹 방식을 사용하며, 이는 성능 병목(Performance Bottleneck)의 원인이 됨.
DFA(Deterministic Finite Automaton) 캐싱을 통해 톰슨 NFA의 성능을 더욱 향상시킬 수 있으며, 실제 구현(Real Implementation)에 적용 가능함.
백트래킹(Backtracking) 방식의 취약점
본문에서는 Perl, Python, PHP, Ruby 등에서 사용되는 백트래킹(Backtracking) 방식의 정규 표현식 엔진이 특정 패턴에서 심각한 성능 저하를 겪는다고 지적한다. 특히 `a?nan`과 같은 정규 표현식에서 `a?` 부분이 여러 번 중첩될 경우, 지수적 시간 복잡도(Exponential Time Complexity)를 가지며, 입력 문자열의 길이가 증가함에 따라 실행 시간이 급격히 증가하는 문제점을 보여준다. 이러한 문제는 DoS(Denial of Service) 공격에 악용될 수 있다.
톰슨 NFA(Thompson NFA) 알고리즘의 우수성
반면, 톰슨 NFA(Thompson NFA) 기반의 정규 표현식 엔진은 선형 시간 복잡도(Linear Time Complexity)를 보장하여 백트래킹 방식의 문제를 해결한다. 톰슨 NFA는 정규 표현식을 NFA(Non-deterministic Finite Automaton)로 변환하고, 이를 통해 문자열을 매칭하는 방식으로 작동한다. 이러한 방식은 입력 문자열을 한 번만 읽으면서 매칭을 수행하므로, 백트래킹 방식에 비해 훨씬 빠르고 예측 가능한 성능을 제공한다. 특히, DFA(Deterministic Finite Automaton) 캐싱을 통해 성능을 더욱 향상시킬 수 있다.
DFA(Deterministic Finite Automaton) 캐싱을 통한 성능 최적화
저자는 톰슨 NFA(Thompson NFA) 알고리즘을 기반으로, DFA(Deterministic Finite Automaton) 캐싱을 구현하여 성능을 개선하는 방법을 제시한다. DFA 캐싱은 NFA의 상태를 캐싱하여, 동일한 상태에 대한 계산을 반복하지 않도록 한다. 이는 메모리 사용량(Memory Usage)을 증가시키지만, 매칭 속도를 크게 향상시킨다. 특히, 실제 환경(Real Environment)에서 정규 표현식 사용 시 성능 병목을 해결하는 데 효과적이다.
실제 언어에서의 정규 표현식 구현
본문은 Java, Perl, Python, Ruby 등에서 사용되는 백트래킹 방식의 정규 표현식 엔진의 문제점을 지적하며, 톰슨 NFA(Thompson NFA) 알고리즘의 대안을 제시한다. 하지만, 이러한 언어들이 기존 구현을 쉽게 변경하기 어렵다는 점을 언급하며, 하위 호환성(Backward Compatibility) 문제와 성능 개선(Performance Improvement) 사이의 균형을 맞춰야 함을 강조한다. 또한, 정규 표현식 최적화(Regular Expression Optimization)를 위한 다양한 기법들을 소개한다.