Сохранённый расчёт 3b1e5ea9-1f25-4dff-808a-58efaae7111f содержит
16 кругов Ø340 мм и 16 кругов Ø223 мм. Оба сохранённых контура имеют по 128
вершин. Лист 3050×2030 мм, зазор 10 мм и отступ от края 10 мм.
В ходе исследования ни расчёт, ни исходные файлы не изменялись.
| Нагрузка | До | После, тот же сервер |
|---|---|---|
| Сохранённый случай с 32 кругами | Сохранённый прогон упал на 17/32 деталях через 60,17 с; прогон cProfile за 20 с дошёл до 11/32 | 32/32 на одном листе; 0,98 с решатель, 1,20 с подпроцесс плюс точная проверка |
| Сохранённый Acceptance 300, прямоугольники 600×387 мм | Существующий принятый результат: 12 листов; прежнее время не записано | 300/300 на 12 листах; 2,20 с решатель, 2,54 с подпроцесс плюс точная проверка |
Старый решатель строил декартово произведение координат X и Y, взятых
с каждого размещённого контура. Число кандидатов быстро росло по мере
накопления деталей. Для каждого кандидата GeoJSON заново разбирался в новый
полигон Shapely, снова поворачивался и нормализовался, после чего часто
вычислялось пересечение полигонов перед проверкой расстояния. В базовом
20-секундном профиле placed_shape/преобразование GeoJSON вызывалось 20 624
раза, а пересечение полигонов — 24 008 раз; было зафиксировано 11,7 млн вызовов
Python. 128-вершинные круги делали эту повторную работу дорогой, но корневой
причиной был взрывной рост числа кандидатов.
Теперь решатель один раз кэширует точные полигоны детали для 0°/90° и ведёт
инкрементальные двумерные опорные точки вместо сетки X×Y. Кэшированные
ограничивающие прямоугольники отбирают возможные столкновения до любого точного
полигонального предиката. Для листов с большим числом размещений на каждую
попытку детали строится один STRtree, который переиспользуется для всех её
кандидатов. Точное расстояние/пересечение контуров остаётся решающим;
сохраняемая раскладка повторно проверяется по полным полигонам. Новые круги
генерируются с адаптивным числом вершин: 64 вершины для Ø340 мм и около
0,25 мм максимального отклонения хорды. Ранее сохранённая геометрия не меняется.
Воркер включает поля времени для подготовки геометрии, генерации кандидатов,
проверки столкновений, расстояния между полигонами, пересечения полигонов,
трансформаций, каждой детали и общего времени решателя. Backend логирует
NESTING_TIMINGS с пятью самыми медленными деталями и временем точной проверки
раскладки. Колбэк прогресса по-прежнему продвигается только при обработке
реальной детали. MAX_NEST_SECONDS=180 — настраиваемый предел безопасности
для прерываемого воркера, а не ожидаемое время работы.
Запустите pytest -q backend/tests/test_nesting_performance.py, чтобы проверить
32 круга старого формата, 300 прямоугольников, смешанные примитивы, сцепляющийся
L-образный контур и вывод времени воркера. Полные проверки сборки backend и
frontend по-прежнему обязательны перед развёртыванием. После обновления кода
backend на systemd-хосте выполните systemctl restart signage-estimator-backend,
проверьте curl http://127.0.0.1:8000/api/health и посмотрите
journalctl -u signage-estimator-backend -n 100 на наличие записей времени.
Текущая песочница не может выполнить этот перезапуск хоста.