먼저 정확성과 시간을 측정해
최적화하기 전에 패턴이 올바른 결과를 내는지 테스트하고 실제 입력으로 실행 시간을 재. 느려 보이는 문제가 잘못된 범위나 과도한 매칭에서 비롯된 정확성 문제일 수도 있어.
1. 재사용할 패턴에 이름 붙이기
re.compile로 만든 패턴 객체는 여러 호출에서 재사용하기 쉽고 의도도 드러내. Python의 모듈 수준 함수도 최근 패턴을 캐시하므로 명시적 컴파일이 언제나 더 빠른 것은 아니야. 반복 경로에서 차이가 중요한지는 측정해.
2. 검색 범위를 정확히 표현하기
입력 시작에서만 매칭해야 한다면 ^를 사용하고, 전체 문자열을 검증한다면 fullmatch 같은 API를 사용해. 불필요한 시작 위치를 시도하지 않게 할 수 있지만, 원래 의도한 매칭 범위를 바꾸지 않는지 먼저 확인해야 해.
3. 한 글자 선택은 문자 클래스로 쓰기
a|b|c처럼 한 글자 대안만 나열한다면 [abc]가 뜻을 더 직접적으로 보여 줘. 엔진이 둘을 비슷하게 최적화할 수도 있으므로 속도 차이는 가정하지 말고 가독성을 먼저 봐.
4. 종료 문자를 문자 클래스로 표현하기
종료 표식이 한 글자라면 .*?X보다 [^X]*X가 어디까지 허용하는지 더 분명하게 드러낼 수 있어. 종료 표식이 여러 글자라면 부정형 문자 클래스 하나로 같은 뜻을 표현할 수 없어. 문자열 검색이나 파서, 의미를 테스트한 다른 패턴을 사용해. 원자 그룹도 백트래킹 선택지를 없애므로 결과가 같다는 검증이 필요해.
5. 왼쪽에 구체적인 단서를 두기
패턴 초반에 고정 문자열이나 좁은 문자 클래스가 있으면 엔진이 맞지 않는 위치를 일찍 버릴 수 있어. 반대로 .*처럼 넓은 시작은 후보 범위를 크게 만들 수 있어. 엔진마다 최적화 방식이 다르므로 실제 입력으로 확인해.
6. 작업에 맞는 엔진과 도구 선택하기
큰 파일을 검색할 때는 선형 시간 보장을 목표로 하는 ripgrep의 기본 정규식 엔진이 유리할 수 있어. 전후방 탐색이나 역참조가 필요하면 다른 엔진을 선택해야 할 수도 있어. 필요한 문법과 입력 크기를 함께 고려해.
7. 대표 입력과 나쁜 입력을 함께 측정해
짧고 정상적인 예시에서 빠른 패턴도 긴 실패 입력에서는 느려질 수 있어. 실제 데이터의 대표 표본과 의도적으로 까다로운 입력을 함께 벤치마크해.