Хотя регулярное выражение regexp обычно дает элегантное и компактное решение, зачастую оно не самое быстрое.
Для задач, в которых необходимо заменить одни подстроки другими, стандартная библиотека предоставляет действительно эффективное решение в видеstrings.Replacer
:
Replacer заменяет список строк заменой.Это безопасно для одновременного использования несколькими программами.
Вы можете создать заменитель многократного использования с strings.NewReplacer()
, где вы перечисляете пары, содержащие заменяемые части и их замены.Если вы хотите выполнить замену, просто позвоните Replacer.Replace()
.
Вот как это будет выглядеть:
const replacement = "<br>\n"
var replacer = strings.NewReplacer(
"\r\n", replacement,
"\r", replacement,
"\n", replacement,
"\v", replacement,
"\f", replacement,
"\u0085", replacement,
"\u2028", replacement,
"\u2029", replacement,
)
func replaceReplacer(s string) string {
return replacer.Replace(s)
}
Вот как решение регулярного выражения из ответ Wiktor выглядит так:
var re = regexp.MustCompile(`\r\n|[\r\n\v\f\x{0085}\x{2028}\x{2029}]`)
func replaceRegexp(s string) string {
return re.ReplaceAllString(s, "<br>\n")
}
Реализация на самом деле довольно быстрая.Вот простой тест, сравнивающий его с вышеупомянутым предварительно скомпилированным решением регулярного выражения:
const input = "1st\nsecond\r\nthird\r4th\u0085fifth\u2028sixth"
func BenchmarkReplacer(b *testing.B) {
for i := 0; i < b.N; i++ {
replaceReplacer(input)
}
}
func BenchmarkRegexp(b *testing.B) {
for i := 0; i < b.N; i++ {
replaceRegexp(input)
}
}
И результаты теста:
BenchmarkReplacer-4 3000000 495 ns/op
BenchmarkRegexp-4 500000 2787 ns/op
Для нашего тестового ввода strings.Replacer
было больше, чем *В 1035 * 5 раз быстрее.
Есть и другое преимущество.В приведенном выше примере мы получаем результат в виде нового значения string
(в обоих решениях).Это требует нового string
распределения.Если нам нужно записать результат в io.Writer
(например, мы создаем ответ HTTP или записываем результат в файл), мы можем избежать создания нового string
в случаеstrings.Replacer
, поскольку у него есть удобный метод Replacer.WriteString()
, который принимает io.Writer
и записывает результат в него, не выделяя и не возвращая его как string
.Это значительно увеличивает прирост производительности по сравнению с решением регулярных выражений.