TL;DR
Исследователи протестировали 6 популярных LLM (DeepSeek-R1, GPT-4.1, Claude-3.7, DeepSeek-V3, Qwen2.5-Coder, Llama-3.3) на 944 задачах LeetCode по 5 языкам программирования. Измеряли Pass@1 (решено с первой попытки), синтаксические ошибки, ошибки выполнения, логические ошибки и неоптимальные алгоритмы (превышение лимита времени). Результат: DeepSeek-R1 и GPT-4.1 стабильно лучшие по всем метрикам, Llama-3.3 худшая. Python и JavaScript дают меньше всего ошибок у всех моделей, Go — больше всего синтаксических проблем.
Главная находка: модели часто генерируют логически верный, но медленный код. Llama-3.3 выдаёт алгоритмы, которые превышают лимит времени в 35-50% задач на разных языках. Даже топовые модели страдают: GPT-4.1 и Claude-3.7 получают Time Limit Exceeded в 15-20% случаев. Причина — LLM мыслит паттернами, не математикой сложности. Модель генерирует "работающее решение" (вложенный цикл, наивный перебор), не просчитывая O(n²) против O(n log n).
Решение простое: добавить в промпт "Оптимизируй сложность алгоритма по времени". Эта одна фраза снижает Time Limit Exceeded на 25-35% у всех моделей. DeepSeek-R1 особенно реагирует — его ошибки оптимальности падают с 15% до 5% на Python. Работает через явное напоминание: модель начинает генерировать не первое рабочее решение, а анализировать варианты и выбирать эффективный алгоритм. Исследование также показало, что структурированный промпт (роль + задача + примеры + ограничения + тесткейсы + инструкции) даёт стабильнее результаты, чем просто "напиши код для...".
Схема подхода
ШАГ 1: Определи роль и язык
"Ты — разработчик. Реши на Python."
ШАГ 2: Дай описание задачи
Чёткая формулировка + примеры входа/выхода
ШАГ 3: Укажи ограничения
Диапазоны значений, граничные условия
ШАГ 4: Дай заготовку кода
Класс/функция с сигнатурой
ШАГ 5: Покажи тесткейсы
Примеры данных для проверки
ШАГ 6: Добавь инструкции
"Только код, без комментариев" +
"Оптимизируй сложность алгоритма по времени"
Всё выполняется в одном промпте, один запрос.
Пример применения
Задача: Нужен скрипт для аналитики продаж. Есть CSV на 100 000 строк (товар, выручка). Надо найти топ-10 товаров по выручке. Первая попытка с ChatGPT выдала код, который считает 2 минуты — клиент ждать не будет.
Промпт:
Ты — Python-разработчик. Реши задачу.
Описание:
Дан список товаров с выручкой. Найди топ-10 по выручке.
Пример:
Вход: [("Ноутбук", 150000), ("Мышь", 500), ("Клавиатура", 2000)]
Выход: [("Ноутбук", 150000), ("Клавиатура", 2000), ("Мышь", 500)]
Ограничения:
- до 100 000 товаров
- выручка от 0 до 10 000 000 рублей
Заготовка:
def top_sales(products: list) -> list:
# твой код
Тесткейсы:
products = [("Товар1", 1000), ("Товар2", 5000), ("Товар3", 3000)]
Ожидается: [("Товар2", 5000), ("Товар3", 3000), ("Товар1", 1000)]
Инструкции:
Только исполняемый код, без объяснений.
Оптимизируй сложность алгоритма по времени — данных может быть много.
Результат:
Модель выдаст код с эффективным алгоритмом сортировки или heap-структурой (O(n log k) вместо O(n²)). Без фразы "оптимизируй" — может вернуть наивный вложенный цикл. С этой фразой DeepSeek-R1 и GPT-4.1 генерируют быстрое решение в 85-90% случаев вместо 60-70%.
Почему это работает
Слабость LLM в кодинге: Модель генерирует по паттернам из обучающих данных, не вычисляя математическую сложность. Она "видит" похожую задачу → выдаёт похожее решение. Если в данных много простых примеров с циклами — она выдаст цикл, даже если он O(n²) на большом массиве. LLM не анализирует "а пройдёт ли это за секунду на 100 000 элементах" — у неё нет понятия времени выполнения, только паттерны текста.
Сильная сторона LLM: Модель отлично следует явным инструкциям и умеет сравнивать варианты решений, если об этом попросить. Когда в промпте написано "оптимизируй сложность" — это триггер для другого паттерна генерации. Модель начинает не просто писать код, а генерировать рассуждение: "для этой задачи есть наивный O(n²) способ и оптимальный O(n log n) через сортировку, выберу второй".
Механика работы: Фраза "оптимизируй сложность алгоритма" работает как контекстный якорь. Без неё модель семплирует из пространства "все рабочие решения" → часто попадает в неэффективные. С ней — семплирует из подпространства "эффективные решения" → вероятность оптимального кода выше. Это работает особенно сильно для reasoning-моделей (DeepSeek-R1), которые обучены делать явные шаги рассуждений перед кодом.
Дополнительные рычаги:
Язык программирования: Python и JavaScript дают на 40-50% меньше синтаксических ошибок, чем Go или C++. Если задача не требует конкретного языка — выбирай Python для максимальной надёжности.
Выбор модели: DeepSeek-R1 и GPT-4.1 решают на 20-30% больше задач с первой попытки, чем Llama-3.3. Если работаешь с кодом постоянно — эти модели стоят своих денег/ресурсов.
Структура промпта: Добавление роли ("ты разработчик"), примеров (вход/выход) и ограничений (размеры данных) снижает количество логических ошибок. LLM лучше работает, когда контекст структурирован, а не просто "напиши функцию для...".
Параметры генерации: Если есть доступ к API — top-p=0.95, temperature=0.1 дают стабильнее результаты для кода, чем дефолтные настройки. Низкая температура убирает "креативность", которая в коде = непредсказуемость.
Шаблон промпта
Ты — {роль} разработчик. Реши задачу на {язык}.
Описание задачи:
{подробное описание что нужно сделать}
Пример:
Вход: {пример входных данных}
Выход: {пример ожидаемого результата}
Объяснение: {как получился результат}
Ограничения:
- {диапазон значений}
- {граничные условия}
- {специфические требования}
Заготовка кода:
{структура класса/функции с сигнатурой}
Тесткейсы:
{пример 1}
{пример 2}
{пример 3}
Инструкции:
Только исполняемый код, без объяснений и комментариев.
Оптимизируй сложность алгоритма по времени.
{дополнительные требования к коду}
Как заполнять:
{роль}— Python / JavaScript / Java / C++ / Go{язык}— тот же язык (Python предпочтительнее для надёжности){описание}— что должен делать код, без технических деталей реализации{примеры}— 1-2 простых случая, показывающих логику работы{ограничения}— размеры данных, диапазоны чисел, особые условия{заготовка}— пустая функция/класс с правильной сигнатурой{тесткейсы}— 2-3 примера для проверки, включая граничные случаи{дополнительные}— стиль кода, обработка ошибок, формат вывода
Ключевая фраза: "Оптимизируй сложность алгоритма по времени" — обязательна, если работаешь с большими данными (>1000 элементов) или сложными вычислениями.
Ограничения
⚠️ Не универсальное решение: Структурированный промпт + "оптимизируй" улучшают результат, но не гарантируют 100% корректность. Даже топовые модели (DeepSeek-R1, GPT-4.1) решают только 70-80% задач с первой попытки. Оставшиеся 20-30% требуют итераций, проверки или человеческой правки.
⚠️ Зависимость от сложности: На простых задачах (сортировка списка, поиск элемента) фраза "оптимизируй" почти не меняет результат — модель и так выдаст нормальный код. Эффект проявляется на средних и сложных задачах (динамическое программирование, графы, комбинаторика), где есть несколько вариантов решения с разной сложностью.
⚠️ Go и C++ проблемнее: Если задача требует Go или C++, готовься к в 2-3 раза большему количеству синтаксических ошибок, чем на Python. Модели хуже знают строгие языки. Может понадобиться несколько попыток или ручная правка синтаксиса.
⚠️ Llama-3.3 слабее для кода: Несмотря на сильные общие способности, Llama-3.3 выдаёт неоптимальные алгоритмы в 35-50% задач даже с фразой "оптимизируй". Если кодинг — основная задача, выбирай DeepSeek-R1, GPT-4.1 или Claude-3.7.
⚠️ Нужна проверка: Любой сгенерированный код нужно тестировать на граничных случаях (пустой массив, максимальные значения, дубликаты). LLM хорошо решают типовые случаи, но пропускают edge cases в 15-20% решений.
Ресурсы
Holistic Evaluation of State-of-the-Art LLMs for Code Generation — Le Zhang, Suresh Kothari (Department of Computer Science, Iowa State University, 2025)
Исследование основано на платформе LeetCode и оценке моделей: DeepSeek-R1, DeepSeek-V3, Qwen2.5-Coder-32B, Llama-3.3-70B, GPT-4.1, Claude-3.7 Sonnet.
Репозиторий с данными: https://figshare.com/s/26448e92798aab34e407
