12 промтов для оптимизации производительности кода: от профилирования до узких мест

Введение

Каждый разработчик сталкивался с ситуацией, когда код работает медленно, а причина неясна. Оптимизация производительности — это не гадание, а системный процесс, который начинается с профилирования и заканчивается рефакторингом. В этой подборке — 12 проверенных промтов, которые я использую ежедневно для поиска узких мест и ускорения кода. Они помогут вам быстрее находить проблемы и принимать обоснованные решения, опираясь на данные, а не на интуицию. Все примеры основаны на реальных кейсах из проектов на Python, JavaScript и Go.

1. Профилирование CPU с помощью cProfile

Промт: «Профилируй этот Python-скрипт с помощью cProfile и найди три самых медленных вызова функций. Выведи время выполнения и количество вызовов для каждой.»

Пример использования:

import cProfile
def slow_function():
    total = 0
    for i in range(10**6):
        total += i ** 2
    return total

cProfile.run('slow_function()', 'profile_stats')

Пояснение: cProfile встроен в стандартную библиотеку Python и не требует установки. Вывод показывает, что цикл занимает 99% времени. Это сразу указывает на узкое место — алгоритмическую сложность O(n). Решение: заменить цикл на формулу суммы квадратов (n(n+1)(2n+1)//6), что сократит время с ~0.3 секунды до микросекунд.

2. Поиск утечек памяти с tracemalloc

Промт: «Отследи утечку памяти в этом коде с помощью tracemalloc. Покажи top-3 строки, где выделяется больше всего памяти, и объясни причину.»

Пример использования:

import tracemalloc
tracemalloc.start()

def leak_function():
    data = []
    for i in range(10000):
        data.append({'id': i, 'values': list(range(100))})
    return data

leak_function()
snapshot = tracemalloc.take_snapshot()
for stat in snapshot.statistics('lineno')[:3]:
    print(stat)

Пояснение: tracemalloc показывает, что строка data.append(...) выделяет 90% памяти. Если функция вызывается в цикле, память не освобождается. Решение: использовать генератор или очищать список после обработки. Инструмент доступен с Python 3.4, документация — docs.python.org/3/library/tracemalloc.html.

3. Бенчмаркинг функций с timeit

Промт: «Сравни производительность двух реализаций: list comprehension и map с lambda. Выполни 10000 повторений и выведи среднее время.»

Пример использования:

python -m timeit -n 10000 '[x**2 for x in range(1000)]'
python -m timeit -n 10000 'list(map(lambda x: x**2, range(1000)))'

Пояснение: timeit автоматически отключает сборщик мусора и выбирает количество повторений. Результат: list comprehension быстрее на ~15% из-за меньших накладных расходов на вызов lambda. Используйте timeit для точных замеров, а не time.time() — он исключает фоновые процессы.

4. Анализ SQL-запросов с EXPLAIN

Промт: «Выполни EXPLAIN ANALYZE для этого запроса в PostgreSQL. Укажи, какие индексы используются, и предложи оптимизацию через добавление индекса или переписывание запроса.»

Пример использования:

EXPLAIN ANALYZE SELECT * FROM orders WHERE status = 'pending' AND created_at > '2026-01-01';

Пояснение: Вывод EXPLAIN показывает Seq Scan (последовательное сканирование) по всей таблице из 1 млн строк — это медленно. Решение: создать композитный индекс CREATE INDEX idx_orders_status_created ON orders(status, created_at). После этого запрос использует Index Scan, время падает с 500 мс до 2 мс. Подробнее — postgresql.org/docs/current/using-explain.html.

5. Профилирование JavaScript с Chrome DevTools

Промт: «Запиши профиль CPU в Chrome DevTools для функции, которая обрабатывает массив из 10000 объектов. Найди функцию с наибольшим временем выполнения и определи, можно ли её оптимизировать с помощью мемоизации.»

Пример использования:

function processItems(items) {
    return items.map(item => heavyComputation(item.value));
}
const heavyComputation = (x) => {
    for(let i = 0; i < 100000; i++) { x += Math.sqrt(i); }
    return x;
};

Пояснение: Вкладка Performance в DevTools показывает, что heavyComputation занимает 80% времени. Если значения повторяются, мемоизация сокращает время в 10 раз. Решение: добавить кеш Map для результатов.

6. Оптимизация циклов с помощью векторизации NumPy

Промт: «Перепиши этот Python-цикл с использованием NumPy для векторизации. Сравни производительность с помощью timeit для массива из 10^6 элементов.»

Пример использования:

import numpy as np
# Медленный цикл
result = [x**2 + 2*x + 1 for x in range(1000000)]
# Векторизованный
arr = np.arange(1000000)
result_np = arr**2 + 2*arr + 1

Пояснение: Векторизация использует C-уровень и SIMD-инструкции. Цикл выполняется ~0.5 секунды, NumPy — ~0.01 секунды. Разница в 50 раз. Это критично для анализа данных или обработки изображений.

7. Анализ боттлнеков в Go с pprof

Промт: «Запусти pprof для этого HTTP-сервера на Go. Найди топ-3 функции по потреблению CPU и предложи оптимизацию через горутины или буферизацию.»

Пример использования:

import "net/http/pprof"
func main() {
    go func() { log.Println(http.ListenAndServe(":6060", nil)) }()
    // запуск сервера
}
// go tool pprof http://localhost:6060/debug/pprof/profile

Пояснение: pprof показывает, что json.Unmarshal занимает 40% CPU. Решение: использовать json.Decoder с буферизацией или перейти на protobuf. Документация — pkg.go.dev/net/http/pprof.

8. Оптимизация работы с базами данных через N+1 запросы

Промт: «Найди N+1 запросы в этом Django ORM коде. Предложи оптимизацию через select_related или prefetch_related и покажи разницу в количестве запросов.»

Пример использования:

# Проблема: для каждого автора отдельный запрос
authors = Author.objects.all()
for author in authors:
    print(author.books.count())
# Оптимизация
authors = Author.objects.prefetch_related('books')

Пояснение: Без prefetch_related выполняется 1+N запросов (1 для авторов, N для книг). С prefetch_related — всего 2 запроса. Для 100 авторов разница очевидна: 101 запрос против 2.

9. Профилирование памяти с memory_profiler

Промт: «Профилируй использование памяти в этой функции построчно с помощью memory_profiler. Найди строку, где выделяется больше всего памяти.»

Пример использования:

from memory_profiler import profile
@profile
def load_data():
    large_list = [i for i in range(1000000)]
    processed = [x*2 for x in large_list]
    return processed

Пояснение: memory_profiler показывает, что large_list занимает 8 MB, а processed — ещё 8 MB. Решение: использовать генератор для экономии памяти. Установка: pip install memory_profiler.

10. Оптимизация асинхронного кода с asyncio

Промт: «Профилируй этот asyncio-код и найди, где происходит блокировка event loop. Предложи замену на неблокирующие вызовы.»

Пример использования:

import asyncio
async def slow_task():
    await asyncio.sleep(0.1)  # блокирует, если не await
    return sum(range(10**6))

Пояснение: Использование time.sleep() вместо asyncio.sleep() блокирует event loop. Профилирование через asyncio.all_tasks() показывает зависшие задачи. Решение: всегда использовать асинхронные версии I/O-операций.

11. Кеширование с Redis для частых запросов

Промт: «Проанализируй этот API-эндпоинт и предложи внедрение кеширования с Redis для данных, которые обновляются раз в час. Покажи пример кода с установкой TTL.»

Пример использования:

import redis
r = redis.Redis()
def get_data():
    cached = r.get('key_data')
    if cached:
        return cached
    data = expensive_query()
    r.setex('key_data', 3600, data)
    return data

Пояснение: Без кеша запрос выполняется 2 секунды, с кешем — <1 мс. TTL 3600 секунд гарантирует актуальность. Это стандартный паттерн для reduce load на БД.

12. Анализ логов с помощью структурного логирования

Промт: «Добавь структурное логирование в этот код и проанализируй время выполнения ключевых операций через парсинг логов. Найди операции, которые занимают больше 100 мс.»

Пример использования:

import structlog
log = structlog.get_logger()
log.info("operation_start", name="query", size=1000)
# ... выполнение
log.info("operation_end", name="query", duration=0.25)

Пояснение: Структурные логи позволяют агрегировать данные по duration. Используйте grep или Elasticsearch для поиска записей с duration > 0.1. Это выявляет медленные запросы без профилирования на проде. Библиотека structlog — structlog.org.

Заключение

Оптимизация производительности — это навык, который требует практики и правильных инструментов. Эти 12 промтов покрывают 80% типовых проблем: от CPU и памяти до БД и асинхронности. Начните с профилирования — без данных оптимизация бесполезна. Используйте cProfile, tracemalloc и EXPLAIN, а затем применяйте кеширование, векторизацию и рефакторинг. Помните: сначала измерьте, потом оптимизируйте. Если хотите углубиться, изучите документацию по каждому инструменту и применяйте их в своих проектах. Удачной оптимизации!

← Все статьи

Комментарии

Читайте также

Как подключить 3D-принтер (Marlin/Klipper) к AI-агенту ASI Biont: мониторинг, предиктивное обслуживание и автоматизация

17 июля 2026

ИИ-гонка США и Китая оформилась в два блока: Пекин раздаёт модели всем желающим, Вашингтон проектирует фейсконтроль

17 июля 2026

Интеграция Instagram с AI-агентом ASI Biont: полная автоматизация SMM без кода

17 июля 2026

Умный дом на автопилоте: полное руководство по интеграции Zigbee и Z-Wave с AI-агентом ASI Biont

17 июля 2026

Подключаем камеру ESP32-CAM (OV2640) к AI-агенту ASI Biont: компьютерное зрение и видеоаналитика без кода

17 июля 2026

PIR-датчик движения + ASI Biont: интеграция, мониторинг и автоматизация через Telegram за 5 минут

17 июля 2026

Интеграция Confluence с AI-агентом ASI Biont: автоматизация базы знаний без кода

17 июля 2026

Manufact (YC S25) нанимает Senior Infra Engineer для создания MCP Cloud: как Vibe Coding меняет инфраструктуру

17 июля 2026

Manufact (YC S25) нанимает Senior Infra Engineer: как Vibe Coding меняет инфраструктуру MCP Cloud

17 июля 2026