0Pricing
Go Academy · Урок

Советы по производительности

Повторно используйте скомпилированные регулярные выражения

«Советы по производительности» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Компиляция требует затрат

Преобразование строки шаблона в используемое регулярное выражение требует ресурсов. Выполнять это при каждом вызове неэффективно, особенно в циклах или часто выполняемом коде.

package main

import (
    "fmt"
    "regexp"
)

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

Скомпилируйте один раз, используйте часто

Главное правило: скомпилируйте шаблон один раз и повторно используйте *regexp.Regexp. Обычно для этого подходит переменная уровня пакета.

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"))
}

Не компилируйте в циклах

Никогда не вызывайте MustCompile внутри цикла. Скомпилируйте шаблон до цикла и используйте одно и то же значение на каждой итерации.

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.Regexp безопасно для одновременного использования несколькими горутинами. Один глобальный экземпляр может обслуживать их все.

package main

import (
    "fmt"
    "regexp"
)

var re = regexp.MustCompile("go")

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

Иногда строки работают быстрее

Для фиксированной буквальной подстроки strings.Contains эффективнее регулярного выражения. Используйте регулярные выражения только тогда, когда Вам действительно нужны возможности шаблонов.

package main

import (
    "fmt"
    "strings"
)

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

Предпочитайте шаблоны с привязкой

Привязка с помощью ^ позволяет движку быстро завершить работу, если начало не совпадает, вместо сканирования всей строки.

package main

import (
    "fmt"
    "regexp"
)

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

Ограничивайте число совпадений

Если Вам нужно всего несколько совпадений, передавайте небольшое значение n методам поиска всех совпадений вместо -1, чтобы остановить поиск раньше.

package main

import (
    "fmt"
    "regexp"
)

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

Остерегайтесь шаблонов с возвратом назад

Движок RE2 в Go избегает катастрофического возврата назад, но слишком общие шаблоны вроде .* всё равно могут просматривать больше данных, чем нужно. Указывайте условия точнее.

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"))
}

Экранируйте динамический ввод

Если шаблон содержит пользовательский текст, экранируйте его с помощью regexp.QuoteMeta, чтобы специальные символы обрабатывались буквально.

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"))
}

Кэшируйте скомпилированные шаблоны

Если шаблоны создаются во время выполнения, храните скомпилированные шаблоны в отображении, используя строку шаблона в качестве ключа, чтобы не компилировать один и тот же шаблон повторно.

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"))
}

Объединяем всё

Хорошо настроенный проверяющий модуль компилирует шаблон один раз, привязывает его к нужному месту и используется совместно во всех вызовах.

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"))
}

Быстрая проверка

Какой совет по производительности регулярных выражений является самым важным?

Итоги: советы по производительности

Вы научились эффективно использовать регулярные выражения:

  • Скомпилируйте шаблон один раз с помощью MustCompile и используйте повторно; это безопасно при одновременном выполнении.
  • Для фиксированных подстрок предпочитайте strings; привязывайте шаблоны и ограничивайте число совпадений.
  • Экранируйте динамический ввод с помощью QuoteMeta и кэшируйте шаблоны, создаваемые во время выполнения.
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))
    }
}

Часто задаваемые вопросы

Урок «Советы по производительности» бесплатный?

Да — полный текст урока «Советы по производительности» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «Советы по производительности»?

Повторно используйте скомпилированные регулярные выражения Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Советы по производительности»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Основы regexp
  2. Поиск и извлечение
  3. Замена текста
  4. Советы по производительности
← Назад к Go Academy