Files
drhider/History/code-fixes/2026-08-20-honest-answer-and-A-implemented.md
T

3.2 KiB
Raw Blame History

2026-08-20 — Честный ответ Sonnet об ускорении + реализация А (v0.0.55)

Честный ответ Sonnet (History/2026-08-20-sonnet-query-honest-speed.md)

Вопрос: можно ли значительно ускорить обработку, не рискуя устойчивостью/таблицами?

Ответ Sonnet (принято, согласуется с замерами):

  • Безопасно ускорить extract_text() на pdfplumber НЕЛЬЗЯ — pdfminer pure Python, CPU-bound, GIL полностью блокирует threading. (Подтверждено: extract_text 64.4с на Spartan10.)
  • A) Безопасно-просто:
    • A1. Threading для .doc (liberta, IO-bound) — N×~120с → ~120с при нескольких .doc.
    • A2. Кэш compiled regex между файлами (проход 2).
  • B) Заметный выигрыш, но с рисками (ОТЛОЖЕНО):
    • B1. ProcessPool по файлам (spawn) — 3 PDF × 25с → ~30с (только 2+ PDF, CPU=2).
    • B2. ProcessPool по страницам (spawn) — Spartan10 64с → ~35с (сложно: content, порядок).
  • C) Не стоит:
    • fork ProcessPool при session в памяти (COW-раздутие, 4Gi на пределе) — только spawn.
    • Threading по страницам/файлам PDF — GIL, ноль.
  • Итог Sonnet: безопасного значительного ускорения ОДНОГО PDF нет. Для набора 2+ PDF — B1. При CPU=2 потолок 2x.

Решение пользователя

«Делай по А, безопасно» — реализованы ТОЛЬКО A1 и A2. B — НЕ отложено (не делаем).

Реализация (v0.0.55)

A1 — threading для .doc (obfuscator.py, проход 1)

  • .doc файлы (конвертация через HTTP liberta, IO-bound) запускаются в ThreadPoolExecutor(max_workers=min(4, N_doc)).
  • Основной цикл сохраняет порядок: для .doc берёт future.result(), остальные — последовательно. progress_cb/порядок start/done не меняются.
  • Выигрыш: HTTP-конвертация .doc перекрывается с CPU-обработкой PDF/docx.

A2 — кэш compiled regex (replacer.py + obfuscator.py)

  • replacer.py: вынесен _build_combined_re(sorted_keys), apply_replacements получил параметр compiled_re=None (если None — компилирует сам).
  • obfuscator.py: после формирования self._sorted_keys компилируется один раз self._compiled_re, передаётся во все вызовы apply_replacements (проход 2).
  • init/finally: _compiled_re инициализируется/очищается.

Проверка

  • Все 106 тестов OK (test_replacer 10/10 — apply_replacements с compiled_re).
  • Интеграция: flat/ (10 файлов) → 5 обработано (EB.md, EB1.md, Spartan10, TKM, mini_78b), битые пропущены, .doc через liberta в потоках. 78.3с (в основном Spartan10 64с extract_text).
  • VERSION 0.0.55.