diff --git a/History/2026-08-19-replacer-optimization.md b/History/2026-08-19-replacer-optimization.md new file mode 100644 index 0000000..2f9f193 --- /dev/null +++ b/History/2026-08-19-replacer-optimization.md @@ -0,0 +1,45 @@ +# v0.0.39 — оптимизация apply_replacements (однопроходная замена) — 2026-08-19 + +**Дата:** 2026-08-19 +**Версия:** 0.0.38 → 0.0.39 +**Файл:** `drhider/replacer.py`, `site/app.py` (версия) + +--- + +## Суть + +Обфускация PDF 19 МБ шла 132.7с, из них ИИ (LLM) всего 7с — остальное (~125с) +тратил основной код. Замер выявил узкое место: `apply_replacements`. + +## Причина + +`apply_replacements` для **каждой** сущности из mapping делала **2 полных +прохода `re.sub` по всему тексту** (основной + фоллбэк `_md_tolerant_pattern`). +Сложность O(N_сущностей × размер_текста × 2) — квадратичная по числу сущностей. +При 300+ сущностей и тексте в несколько МБ — десятки секунд. + +Замер (0.9 МБ, 304 сущности): **17.3 с**. + +## Решение + +Однопроходная замена: +- Все ключи собираются в **один** regex-паттерн через альтернацию `(?:...|...)` + (по убыванию длины, с `re.escape`, границы `(?