# 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`, границы `(?