성능 참고 사항
패턴을 신중하게 컴파일하기
성능 참고 사항은(는) CoddyKit의 무료 C++ Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C++ Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C++ Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
컴파일 비용이 큽니다
문자열에서 std::regex를 만들면 패턴이 컴파일되므로 비용이 많이 듭니다. 가장 효과적인 방법은 한 번 컴파일한 뒤 재사용하는 것입니다.
- 반복문 안에서 정규 표현식을 생성하지 마세요.
- 시작할 때 또는 처음 사용할 때 컴파일하세요.
#include <iostream>
#include <regex>
int main() {
std::regex p("\\d+");
std::string inputs[] = {"12", "ab", "99"};
for (const auto& s : inputs) {
std::cout << s << ": " << std::regex_match(s, p) << '\n';
}
return 0;
}컴파일된 패턴 재사용
반복문 바깥에서 패턴을 한 번 생성하고 모든 입력에 재사용하세요. 매 반복마다 다시 만들면 시간이 낭비됩니다.
#include <iostream>
#include <regex>
#include <vector>
int main() {
static const std::regex p("[a-z]+");
std::vector<std::string> words = {"hello", "WORLD", "cpp"};
int matches = 0;
for (const auto& w : words) {
if (std::regex_match(w, p)) ++matches;
}
std::cout << "Matched: " << matches << '\n';
return 0;
}상수에 정적 상수 사용
절대 바뀌지 않는 패턴이라면 함수 안에서 정적 상수로 선언하여 모든 호출에 걸쳐 정확히 한 번만 컴파일되도록 하세요.
#include <iostream>
#include <regex>
bool isEmail(const std::string& s) {
static const std::regex p("\\w+@\\w+\\.\\w+");
return std::regex_match(s, p);
}
int main() {
std::cout << std::boolalpha;
std::cout << isEmail("a@b.com") << '\n';
std::cout << isEmail("nope") << '\n';
return 0;
}올바른 문법 선택
정규 표현식 종류(문법)는 속도와 기능에 영향을 줍니다. std::regex::ECMAScript는 기본값이며 기능이 가장 풍부하고, std::regex::basic이나 extended는 더 단순하며 때로는 더 빠릅니다.
#include <iostream>
#include <regex>
int main() {
std::regex p("a+", std::regex::extended);
std::cout << std::boolalpha << std::regex_match("aaa", p) << '\n';
return 0;
}최적화 플래그
std::regex::optimize를 추가하면 엔진이 패턴을 구성하는 데 더 많은 시간을 쓰는 대신 더 빠르게 일치하도록 할 수 있습니다. 이는 매우 많은 횟수로 일치시킬 때 효과가 있습니다.
#include <iostream>
#include <regex>
int main() {
std::regex p("\\d{3}-\\d{4}", std::regex::optimize);
std::cout << std::boolalpha << std::regex_match("123-4567", p) << '\n';
return 0;
}치명적인 역추적 피하기
(a+)+ 같은 중첩 수량자는 특정 입력에서 지수 시간으로 폭증할 수 있습니다. 더 단순하고 모호하지 않은 패턴을 사용하세요.
#include <iostream>
#include <regex>
int main() {
std::regex good("a+b");
std::cout << std::boolalpha << std::regex_match("aaaab", good) << '\n';
return 0;
}가능하면 앵커 사용하기
^와 $로 고정하면 엔진이 모든 시작 위치를 시도하는 대신 빠르게 실패할 수 있습니다.
#include <iostream>
#include <regex>
int main() {
std::regex p("^[a-z]{3}$");
std::cout << std::boolalpha;
std::cout << std::regex_search("abc", p) << '\n';
std::cout << std::regex_search("abcd", p) << '\n';
return 0;
}가능하면 단순한 도구 사용하기
고정된 부분 문자열 확인만 필요하다면 std::string::find가 정규 표현식보다 훨씬 빠릅니다. 실제 패턴 일치가 필요할 때만 reserve 정규 표현식을 사용하세요.
#include <iostream>
#include <string>
int main() {
std::string s = "hello world";
bool has = s.find("world") != std::string::npos;
std::cout << std::boolalpha << has << '\n';
return 0;
}일치 객체 재사용
반복해서 검색할 때는 매번 새 객체를 할당하는 대신 하나의 std::smatch를 재사용하여 오버헤드를 줄이세요.
#include <iostream>
#include <regex>
#include <vector>
int main() {
static const std::regex p("(\\d+)");
std::smatch m;
std::vector<std::string> data = {"x1", "y22", "z333"};
for (const auto& s : data) {
if (std::regex_search(s, m, p)) std::cout << m[1] << ' ';
}
std::cout << '\n';
return 0;
}패턴을 더 구체화하기
구체적인 문자 클래스는 모든 문자를 나타내는 점보다 더 빠르고 안전하게 일치합니다. 숫자를 의미할 때는 [0-9] 대신 .을 사용하는 것이 좋습니다.
#include <iostream>
#include <regex>
int main() {
std::regex specific("[0-9]{2}");
std::cout << std::boolalpha;
std::cout << std::regex_match("42", specific) << '\n';
std::cout << std::regex_match("ab", specific) << '\n';
return 0;
}최적화하기 전에 측정하기
<chrono>에서 배운 내용을 함께 활용해 보세요. 변경 사항을 적용하기 전에 정규식 사용 시간을 측정하여 실제로 도움이 되는지 확인하세요.
#include <iostream>
#include <regex>
#include <chrono>
int main() {
using namespace std::chrono;
static const std::regex p("\\d+");
auto s = steady_clock::now();
int hits = 0;
for (int i = 0; i < 1000; ++i) {
if (std::regex_search(std::string("x") + std::to_string(i), p)) ++hits;
}
auto e = steady_clock::now();
std::cout << "hits=" << hits << ", timed: " << ((e - s).count() >= 0) << '\n';
return 0;
}빠른 확인
정규식 성능에 대한 이해도를 확인해 보세요.
복습
정규식을 효율적으로 사용하는 방법을 배웠습니다.
- 패턴을 한 번만, 가능하면
static const로 컴파일하고 재사용하기 - 적절한 문법을 선택하고
optimize를 고려하기 - 치명적인 역추적을 피하고 가능하면 앵커를 사용하기
- 고정된 부분 문자열에는
find같은 더 간단한 도구를 사용하고 변경 사항을 측정하기
이것으로 정규 표현식 과정이 끝났습니다.
자주 묻는 질문
“성능 참고 사항” 강의는 무료인가요?
네 — “성능 참고 사항” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C++ Academy 강의 전체를 잠금 해제할 수 있습니다. C++ Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“성능 참고 사항”에서 뭘 배우나요?
패턴을 신중하게 컴파일하기 브라우저에서 직접 실행하는 실습 코드로 C++ Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
C++ Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 C++ Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“성능 참고 사항” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 C++ Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 C++ Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.