0Pricing
C++ Academy · 강의

성능 참고 사항

패턴을 신중하게 컴파일하기

성능 참고 사항은(는) 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 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. regex 기초
  2. 캡처 그룹
  3. 검색과 대체
  4. 성능 참고 사항
← C++ Academy(으)로 돌아가기