Советы по производительности
Повторно используйте скомпилированные регулярные выражения
«Советы по производительности» — бесплатный урок 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 — локальная установка не требуется.
Все уроки этого курса
- Основы regexp
- Поиск и извлечение
- Замена текста
- Советы по производительности