Классический паттерн очистки строк, который встречается в приложениях:
while (text.Contains(" "))
{
text = text.Replace(" ", "");
}На первый взгляд — читаемо и предсказуемо. На практике — источник проблем под нагрузкой.
Строки в .NET иммутабельны. Каждый вызов
Replace() — это полная аллокация новой строки, копирование содержимого и выброс старого объекта на съедение GC. При длинных прогонах повторяющихся символов цикл делает это многократно. Сложность — O(n²), давление на GC — ощутимое.Правильная замена —
Regex.Replace с квантификатором +:text = Regex.Replace(text, @"-+", "-");
Один проход по строке, одна аллокация результата, линейная сложность.«+» означает одно или более вхождений подряд — именно то, что имелось в виду в цикле, но выражено декларативно.
Оптимальный вариант для .NET 8+ — Source-Generated Regex:
public partial class StringNormalizer
{
[GeneratedRegex(@"-+")]
private static partial Regex ConsecutiveDashRegex();
public static string NormalizeSlug(string input)
=> ConsecutiveDashRegex().Replace(input, "-");
}
Атрибут
[GeneratedRegex] переносит компиляцию паттерна на этап сборки. В рантайме — никакого парсинга, никаких лишних аллокаций при инициализации, валидация паттерна прямо в IDE.📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#il_люминатор