C++ Academy · leksjon

Ytelsesmerknader

Kompiler mønstre med omtanke

Leksjon 4 av 413 trinn

Ytelsesmerknader er en gratis leksjon i C++ Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i C++ Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i C++ Academy inneholder totalt 4 leksjoner.

Kompilering er kostbart

Når du bygger en std::regex fra en streng, kompileres mønsteret, og dette er kostbart. Den største gevinsten får du ved å kompilere én gang og gjenbruke mønsteret.

  • Unngå å konstruere regex inne i løkker.
  • Kompiler ved oppstart eller første gangs bruk.
#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;
}

Gjenbruke et kompilert mønster

Konstruer mønsteret én gang utenfor løkken, og gjenbruk det for hver inndata. Det sløser med tiden å bygge det på nytt for hver iterasjon.

#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;
}

static const for konstanter

Hvis et mønster aldri endres, deklarerer du det som static const inne i en funksjon, slik at det kompileres nøyaktig én gang på tvers av alle kall.

#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;
}

Velge riktig grammatikk

Regex-varianten (grammatikken) påvirker hastighet og funksjoner. std::regex::ECMAScript er standardvalget og det mest omfattende; std::regex::basic eller extended er enklere og noen ganger raskere.

#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;
}

optimize-flagget

Når du legger til std::regex::optimize, ber du motoren bruke mer tid på å bygge mønsteret i bytte mot raskere samsvar. Dette lønner seg når du sammenligner mange ganger.

#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;
}

Unngå katastrofal tilbakesporing

Nestede kvantorer som (a+)+ kan føre til eksponentielt lang kjøretid for bestemte inndata. Foretrekk enklere og entydige mønstre.

#include <iostream>
#include <regex>

int main() {
    std::regex good("a+b");
    std::cout << std::boolalpha << std::regex_match("aaaab", good) << '\n';
    return 0;
}

Bruk ankere når det er mulig

Med ankere som ^ og $ kan motoren gi opp raskt i stedet for å prøve alle startposisjoner.

#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;
}

Foretrekk enkle verktøy når det er mulig

Hvis du bare trenger å kontrollere en fast delstreng, er std::string::find langt raskere enn et regex. Bruk regex når du faktisk trenger mønstergjenkjenning.

#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;
}

Gjenbruke samsvarsobjektet

Når du søker gjentatte ganger, bør du gjenbruke én std::smatch i stedet for å opprette en ny hver gang. Da reduserer du ekstrakostnaden.

#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;
}

Avgrens mønsteret

Spesifikke tegnklasser matcher raskere og sikrere enn jokertegnet punktum. Foretrekk [0-9] fremfor . når du mener sifre.

#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;
}

Mål før du optimaliserer

Kombiner det du har lært om <chrono>: mål tiden for bruken av regulære uttrykk for å bekrefte at en endring faktisk hjelper, før du tar den i bruk.

#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;
}

Hurtigsjekk

Test forståelsen din av ytelsen til regulære uttrykk.

Oppsummering

Du har lært hvordan du bruker regulære uttrykk effektivt:

  • kompiler mønstre én gang, helst som static const, og gjenbruk dem
  • velg riktig grammatikk og vurder optimize
  • unngå katastrofal tilbakesporing, og bruk forankring når det er mulig
  • bruk enklere verktøy som find for faste delstrenger, og mål endringene

Det var siste del av kurset Regular Expressions.

Gratis å komme i gang

Lær deg C++ med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
51
Leksjoner
203

Ofte stilte spørsmål

Er leksjonen «Ytelsesmerknader» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien C++ Academy, inkludert «Ytelsesmerknader», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i C++ Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Ytelsesmerknader»?

Kompiler mønstre med omtanke Du øver på C++ Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med C++ Academy?

Ingen tidligere erfaring er nødvendig. C++ Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.

Hvor lang tid tar leksjonen «Ytelsesmerknader»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne C++ Academy-leksjonen?

Ja. Alle C++ Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Grunnleggende om regex
  2. Fangegrupper
  3. Søk og erstatt
  4. Ytelsesmerknader
← Tilbake til C++ Academy