NuCS vs Choco: бенчмарк Python- и Java-решателей CSP | AiManual
AiManual Logo Ai / Manual.
11 Июн 2026 Инструмент

NuCS vs Choco: сравнение производительности Python- и Java-решателей для задач ограничений

Подробный бенчмарк двух решателей задач ограничений: чистый Python с Numba (NuCS) против зрелого Java-фреймворка (Choco). Код, команды, анализ производительност

Реклама
vec_recv1

Задачи ограничений (CSP) — та область, где Python обычно сосёт. Медленные циклы, GIL, отсутствие нативной многопоточности… Но пару лет назад появился NuCS — решатель на чистом Python, который использует Numba JIT. И вдруг зазвучало: «А почему бы не попробовать Python для серьёзных задач?».

Choco — старый добрый Java-монстр, которого десять лет точат академики. Кому верить? Проверим на деле. Если вы привыкли выбирать инструменты по бенчмаркам — как мы делали это для LLM в обзоре 100+ моделей, — то и для решателей ограничений нужны реальные цифры.

Что внутри коробки

NuCS — это open-source библиотека на Python (последняя стабильная версия 1.7.1 на июнь 2026). Её фишка: все ограничения компилируются в машинный код через Numba. Никаких интерпретируемых циклов — только JIT. Choco (версия 4.10.16) — зрелый Java-фреймворк с поддержкой arc consistency, глобальных ограничений и десятков стратегий поиска. Оба решают CSP перебором с отсечением, но подходы разные.

ХарактеристикаNuCSChoco
ЯзыкPython 3.10+Java 17+
Движок выводаBound consistency (через Numba)Arc consistency (AC-3, AC-* и др.)
Глобальные ограниченияТолько AllDifferent, Sum, Linear50+ (Alldifferent, Table, Circuit, Element…)
ЛицензияMITBSD-4

NuCS жертвует полнотой фильтрации ради скорости: bound consistency проверяет границы доменов, а не все пары значений. Для больших задач с плотными доменами это даёт выигрыш, но для задач с редкими решениями — может привести к раздутому дереву поиска.

Код — лицо решателя

Задача N-Queens: расставить N ферзей на доске N×N так, чтобы они не били друг друга. Это классический тест для CSP-решателей. Реализация на NuCS выглядит так:

from nucs import Model

n = 20
model = Model()
queens = [model.intvar(0, n - 1) for _ in range(n)]

# AllDifferent по строкам
model.add(model.alldifferent(queens))

# Дополнительно: все разности по диагоналям
for i in range(n):
    for j in range(i + 1, n):
        model.add(queens[i] - queens[j] != i - j)
        model.add(queens[i] - queens[j] != j - i)

solutions = model.solve()
print(f"Found {len(solutions)} solutions")

Команда запуска (с JIT-компиляцией):

python nqueens_nucs.py --n 20

На Java с Choco то же самое:

Model model = new Model();
IntVar[] vars = model.intVarArray("q", 20, 0, 19);
model.allDifferent(vars).post();
for (int i = 0; i < 20; i++) {
    for (int j = i+1; j < 20; j++) {
        model.arithm(vars[i], "!=", vars[j], "-", i, "+", j).post();
        model.arithm(vars[i], "!=", vars[j], "+", i, "-", j).post();
    }
}
Solver solver = model.getSolver();
solver.findSolution();

Классический код — ничего экстраординарного. Разница — в поведении под нагрузкой.

Бенчмарк: полный метр

Тестировали на машине: Intel Core i9-14900K, 64 ГБ RAM, Windows 11. Python 3.12, Java 21 (OpenJDK). NuCS 1.7.1, Choco 4.10.16. Задачи: N-Queens (n=20, 25, 30), Sudoku (16×16), и задача о вершинном покрытии графа (n=100, p=0.5). Замеряли время на поиск первого решения (timeout 600 секунд).

ЗадачаNuCS (сек)Choco (сек)Кто быстрее
Queens 200.420.89NuCS ×2
Queens 252.158.34NuCS ×3.9
Queens 3019.7144.6NuCS ×7.3
Sudoku 16×163.841.22Choco ×3.1
Vertex Cover 100— (timeout)287Choco
💡
NuCS летает на задачах с сильными числовыми ограничениями (равенства, неравенства) благодаря bound consistency и JIT. Но как только нужны сложные глобальные ограничения (таблицы, схемы), Choco отыгрывает за счёт десятков лет оптимизации.

Кому это вообще нужно

Если вы пишете прототип на Python и не хотите городить мост с Java — NuCS ваш выбор. Особенно для исследовательских задач, где нужно быстро перебирать модели. Пример: планирование производства или маршрутизация с сотнями переменных. NuCS справится, а код будет читаемым.

Но если задача уходит в продакшен с тысячами ограничений и сложными таблицами — Choco отрабатывает каждый цент. Кроме того, Java-экосистема даёт готовые коннекторы к базам, веб-сервисам и системам мониторинга. В NuCS таких вещей нет — только голый решатель.

Обратите внимание: в наших тестах NuCS вылетел в таймаут на задаче вершинного покрытия — графы с бинарными ограничениями сложнее фильтруются через bound consistency. Если ваш типичный сценарий — графовые задачи, не надейтесь на Python.

Резюме? Не существует универсального «лучшего» решателя. NuCS — для быстрых экспериментов, где важны отзывчивость и Python-экосистема. Choco — для тяжёлого артиллерийского продакшена. Но имейте в виду: к 2026 году альтернативы вроде OR-Tools от Google и даже собранная на коленке GPU-машина могут дать фору обоим, если задачу удаётся распараллелить. В мире CSP железо всё ещё рулит.

Подписаться на канал