0Pricing
Go Academy · Lekcja

Wskazówki dotyczące wydajności

Ponownie używaj skompilowanych regexpów

Wskazówki dotyczące wydajności to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.

Kompilacja ma koszt

Przekształcenie tekstu wzorca w użyteczny regexp wymaga pracy. Wykonywanie tego przy każdym wywołaniu marnuje czas, szczególnie w pętlach lub często wykonywanych fragmentach kodu.

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("[0-9]+")
    fmt.Println(re.MatchString("x9"))
}

Kompiluj raz, używaj wielokrotnie

Złota zasada: skompiluj wzorzec raz i używaj ponownie obiektu *regexp.Regexp. Zwykle przechowuje się go w zmiennej na poziomie pakietu.

package main

import (
    "fmt"
    "regexp"
)

var numRe = regexp.MustCompile("[0-9]+")

func hasNumber(s string) bool {
    return numRe.MatchString(s)
}

func main() {
    fmt.Println(hasNumber("a1"))
    fmt.Println(hasNumber("abc"))
}

Unikaj kompilowania w pętlach

Nigdy nie wywołuj MustCompile wewnątrz pętli. Skompiluj wzorzec przed pętlą i używaj tej samej wartości w każdej iteracji.

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("[a-z]+")
    inputs := []string{"go", "123", "rust"}
    for _, s := range inputs {
        fmt.Println(s, re.MatchString(s))
    }
}

Regexp można bezpiecznie współdzielić

Skompilowany obiekt *regexp.Regexp jest bezpieczny we współbieżnym użyciu przez wiele goroutines. Jedna globalna instancja może obsłużyć je wszystkie.

package main

import (
    "fmt"
    "regexp"
)

var re = regexp.MustCompile("go")

func main() {
    fmt.Println(re.MatchString("golang"))
}

Czasami strings jest szybsze

W przypadku stałego dosłownego podłańcucha strings.Contains jest szybsze niż regexp. Po wyrażenia regularne sięgaj tylko wtedy, gdy rzeczywiście potrzebujesz możliwości wzorców.

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Contains("hello world", "world"))
}

Preferuj wzorce zakotwiczone

Zakotwiczenie za pomocą ^ pozwala silnikowi szybko zakończyć działanie, gdy początek nie pasuje, zamiast przeszukiwać cały napis.

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("^https?://")
    fmt.Println(re.MatchString("http://site"))
    fmt.Println(re.MatchString("see http://x"))
}

Ograniczaj liczbę dopasowań

Gdy potrzebują Państwo tylko kilku dopasowań, przekażcie małą wartość n do metod wyszukujących wszystkie dopasowania zamiast -1, aby zakończyć wyszukiwanie wcześniej.

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile("[0-9]+")
    fmt.Println(re.FindAllString("1 2 3 4 5", 2))
}

Uważaj na wzorce z backtrackingiem

Silnik RE2 używany przez Go unika katastrofalnego backtrackingu, ale zbyt szerokie wzorce, takie jak .*, nadal mogą przeszukiwać więcej danych, niż potrzeba. Określaj wzorce precyzyjnie.

package main

import (
    "fmt"
    "regexp"
)

func main() {
    broad := regexp.MustCompile(".*=.*")
    precise := regexp.MustCompile("[a-z]+=[0-9]+")
    fmt.Println(broad.MatchString("x=1"), precise.MatchString("x=1"))
}

Eskapuj dane dynamiczne

Jeśli wzorzec zawiera tekst pochodzący od użytkownika, poddaj go działaniu regexp.QuoteMeta, aby znaki specjalne były traktowane dosłownie.

package main

import (
    "fmt"
    "regexp"
)

func main() {
    user := "a.b"
    re := regexp.MustCompile(regexp.QuoteMeta(user))
    fmt.Println(re.MatchString("a.b"))
    fmt.Println(re.MatchString("axb"))
}

Buforuj skompilowane wzorce

Jeśli wzorce są tworzone w czasie działania programu, przechowuj skompilowane wzorce w mapie, używając tekstu wzorca jako klucza, aby uniknąć ponownej kompilacji tego samego wzorca.

package main

import (
    "fmt"
    "regexp"
)

var cache = map[string]*regexp.Regexp{}

func get(p string) *regexp.Regexp {
    if re, ok := cache[p]; ok {
        return re
    }
    re := regexp.MustCompile(p)
    cache[p] = re
    return re
}

func main() {
    fmt.Println(get("[0-9]+").MatchString("7"))
}

Łączymy wszystko

Dobrze zoptymalizowany walidator kompiluje wzorzec raz, zakotwicza go i jest współdzielony przez wszystkie wywołania.

package main

import (
    "fmt"
    "regexp"
)

var emailRe = regexp.MustCompile("^[a-z0-9]+@[a-z]+\\.[a-z]+$")

func main() {
    fmt.Println(emailRe.MatchString("me@site.com"))
}

Szybkie sprawdzenie

Jaka jest najważniejsza wskazówka dotycząca wydajności regexp?

Podsumowanie: wskazówki dotyczące wydajności

Nauczyli się Państwo wydajnie używać regexp:

  • Kompiluj raz za pomocą MustCompile i używaj ponownie; obiekt jest bezpieczny we współbieżnym użyciu.
  • W przypadku stałych podłańcuchów preferuj strings; zakotwiczaj wzorce i ograniczaj liczbę dopasowań.
  • Eskapuj dane dynamiczne za pomocą QuoteMeta i buforuj wzorce tworzone w czasie działania programu.
package main

import (
    "fmt"
    "regexp"
)

var re = regexp.MustCompile("^\\d{4}$")

func main() {
    for _, s := range []string{"1234", "12"} {
        fmt.Println(s, re.MatchString(s))
    }
}

Często zadawane pytania

Czy lekcja „Wskazówki dotyczące wydajności” jest bezpłatna?

Tak — pełny tekst „Wskazówki dotyczące wydajności” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wskazówki dotyczące wydajności”?

Ponownie używaj skompilowanych regexpów Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Go Academy?

Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Wskazówki dotyczące wydajności”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?

Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Podstawy regexp
  2. Wyszukiwanie i wyodrębnianie
  3. Zastępowanie tekstu
  4. Wskazówki dotyczące wydajności
← Powrót do Go Academy