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

Введение

Каждый разработчик сталкивался с ситуацией, когда код работает, но медленно. Приложения тормозят, серверы задыхаются от нагрузки, а пользователи уходят к конкурентам. Оптимизация производительности кода — это не просто «сделать быстрее», а системный процесс поиска узких мест и их устранения. Согласно отчёту Google Web Vitals, задержка в 1 секунду при загрузке страницы снижает конверсию на 20% (источник: Google Research, 2021). Но как найти эти самые узкие места в коде, особенно в сложных проектах? Здесь на помощь приходят промты — структурированные запросы к AI-моделям, которые ускоряют анализ и генерацию оптимизированных решений.

В этой подборке я собрал 15 промтов, разделённых на три уровня сложности: базовые (для новичков), продвинутые (для опытных разработчиков) и экспертные (для архитекторов и senior-инженеров). Каждый промт сопровождается реальным примером использования и кодом. Вы сможете сразу применить их в своих проектах.

Базовая категория: для новичков

1. Поиск узких мест в Python-коде

Задача: Проанализировать простой скрипт на Python и найти медленные участки.
Промт: «Напиши код на Python, который вычисляет сумму квадратов чисел от 1 до 10⁶ с помощью цикла и спискового включения. Затем сравни время выполнения обоих подходов с помощью timeit. Определи, какой метод быстрее и почему.»
Пример результата:

import timeit

# Цикл
def sum_with_loop():
    total = 0
    for i in range(1, 10**6):
        total += i * i
    return total

# Списковое включение
def sum_with_comprehension():
    return sum(i*i for i in range(1, 10**6))

print('Loop:', timeit.timeit(sum_with_loop, number=100))
print('Comprehension:', timeit.timeit(sum_with_comprehension, number=100))

Результат покажет, что списковое включение быстрее на 15-20% из-за оптимизации на уровне C. Это базовый пример, который учит профилировать простые операции.

2. Оптимизация SQL-запросов

Задача: Улучшить производительность SQL-запроса, который выполняется медленно.
Промт: «Дан SQL-запрос, который выбирает заказы за последний месяц. Он выполняется 5 секунд. Оптимизируй его, добавив индексы и изменив структуру. Объясни, почему твой вариант быстрее.»
Пример результата:

-- Исходный запрос
SELECT * FROM orders WHERE order_date > '2026-06-18';

-- Оптимизированный запрос
CREATE INDEX idx_order_date ON orders(order_date);
SELECT order_id, customer_id, total FROM orders WHERE order_date > '2026-06-18';

Индекс ускоряет поиск по дате, а выборка только нужных столбцов уменьшает объём данных. Это базовый навык для любого разработчика, работающего с БД.

3. Профилирование времени выполнения функции

Задача: Измерить время выполнения функции с помощью декоратора.
Промт: «Создай декоратор на Python, который замеряет время выполнения функции и выводит результат в секундах. Примени его к функции, вычисляющей факториал 1000 рекурсивно, и сравни с итеративным подходом.»
Пример результата:

import time
from functools import wraps

def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        end = time.perf_counter()
        print(f'{func.__name__} took {end - start:.6f} sec')
        return result
    return wrapper

@timer
def factorial_rec(n):
    return 1 if n == 0 else n * factorial_rec(n-1)

@timer
def factorial_iter(n):
    result = 1
    for i in range(2, n+1):
        result *= i
    return result

factorial_rec(500)
factorial_iter(500)

Итеративный подход будет быстрее из-за отсутствия накладных расходов на рекурсию. Этот пример учит основам профилирования.

4. Оптимизация работы с памятью в Python

Задача: Уменьшить потребление памяти при работе с большими списками.
Промт: «Напиши код, который создаёт список чисел от 1 до 10⁷, и сравни потребление памяти при использовании списка и генератора. Используй sys.getsizeof и tracemalloc для анализа.»
Пример результата:

import sys
import tracemalloc

# Список
tracemalloc.start()
big_list = [x for x in range(10**7)]
snapshot1 = tracemalloc.take_snapshot()

# Генератор
tracemalloc.start()
big_gen = (x for x in range(10**7))
snapshot2 = tracemalloc.take_snapshot()

print('List memory:', sys.getsizeof(big_list))
print('Generator memory:', sys.getsizeof(big_gen))

Генератор занимает считанные байты, в то время как список — десятки мегабайт. Это критично для приложений с ограниченной памятью.

5. Ускорение работы с файлами

Задача: Оптимизировать чтение большого текстового файла.
Промт: «Дан текстовый файл размером 1 ГБ. Напиши код на Python, который читает его построчно и считает количество строк. Сравни производительность трёх подходов: readlines(), цикл по файлу и использование mmap
Пример результата:

import mmap
import time

# Подход 1: readlines
start = time.time()
with open('big_file.txt', 'r') as f:
    lines = f.readlines()
    count = len(lines)
print('readlines:', time.time() - start)

# Подход 2: цикл по файлу
start = time.time()
with open('big_file.txt', 'r') as f:
    count = sum(1 for _ in f)
print('loop:', time.time() - start)

# Подход 3: mmap
start = time.time()
with open('big_file.txt', 'r+b') as f:
    with mmap.mmap(f.fileno(), 0) as mm:
        count = mm.count(b'\n')
print('mmap:', time.time() - start)

mmap обычно быстрее в 2-3 раза, так как работает с памятью напрямую.

Продвинутая категория: для опытных разработчиков

6. Профилирование многопоточного кода

Задача: Найти узкие места в многопоточном приложении.
Промт: «Напиши пример многопоточного скачивания файлов с помощью threading и concurrent.futures. Используй cProfile и threading.Thread для профилирования. Определи, где возникает блокировка GIL.»
Пример результата:

import threading
import cProfile

def download_file(url):
    import time
    time.sleep(0.1)  # имитация I/O

threads = []
for i in range(10):
    t = threading.Thread(target=download_file, args=(f'url_{i}',))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

Профилирование покажет, что CPU-bound задачи не ускоряются из-за GIL, а I/O-bound — ускоряются. Это понимание важно для выбора модели параллелизма.

7. Оптимизация алгоритмов сортировки

Задача: Выбрать оптимальный алгоритм сортировки для конкретного случая.
Промт: «Сравни производительность встроенной сортировки Python, quicksort и timsort на массиве из 10⁶ случайных чисел. Используй timeit и matplotlib для визуализации.»
Пример результата:

import timeit
import random

data = [random.random() for _ in range(10**6)]

# Сортировка Python (Timsort)
time1 = timeit.timeit(lambda: sorted(data), number=10)

# Quicksort (реализация)
def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)

time2 = timeit.timeit(lambda: quicksort(data), number=10)

print('Timsort:', time1)
print('Quicksort:', time2)

Timsort обычно быстрее на реальных данных благодаря адаптации к частично отсортированным массивам.

8. Оптимизация кэширования с помощью lru_cache

Задача: Ускорить рекурсивные вычисления с помощью мемоизации.
Промт: «Используй functools.lru_cache для оптимизации рекурсивного вычисления чисел Фибоначчи. Сравни время выполнения с обычной рекурсией и итеративным методом.»
Пример результата:

from functools import lru_cache
import timeit

@lru_cache(maxsize=100)
def fib_cached(n):
    if n < 2:
        return n
    return fib_cached(n-1) + fib_cached(n-2)

def fib_iter(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

print('Cached:', timeit.timeit(lambda: fib_cached(30), number=1000))
print('Iter:', timeit.timeit(lambda: fib_iter(30), number=1000))

Кэширование сокращает время с экспоненциального до линейного.

9. Оптимизация работы с NumPy

Задача: Ускорить математические операции с помощью векторизации.
Промт: «Напиши код, который вычисляет сумму квадратов матрицы 1000x1000 с помощью циклов Python и с помощью NumPy. Сравни время выполнения.»
Пример результата:

import numpy as np
import time

matrix = np.random.rand(1000, 1000)

# Циклы
def loop_sum():
    total = 0
    for i in range(1000):
        for j in range(1000):
            total += matrix[i][j] ** 2
    return total

# NumPy
def numpy_sum():
    return np.sum(matrix ** 2)

start = time.time()
loop_sum()
print('Loop:', time.time() - start)

start = time.time()
numpy_sum()
print('NumPy:', time.time() - start)

NumPy быстрее в 50-100 раз благодаря векторизации на C.

10. Анализ производительности с помощью py-spy

Задача: Использовать сэмплирующий профилировщик для поиска узких мест в работающем приложении.
Промт: «Напиши скрипт, который имитирует CPU-bound нагрузку (цикл с большими вычислениями). Затем используй py-spy для профилирования в реальном времени и определи, какая функция потребляет больше всего CPU.»
Пример результата:

import time

def heavy_compute():
    total = 0
    for i in range(10**7):
        total += i ** 0.5
    return total

def main():
    import threading
    threads = []
    for _ in range(4):
        t = threading.Thread(target=heavy_compute)
        threads.append(t)
        t.start()
    for t in threads:
        t.join()

if __name__ == '__main__':
    main()

Запусти py-spy record -o profile.svg -- python script.py и посмотри flamegraph.

Экспертная категория: для архитекторов и senior-инженеров

11. Оптимизация с помощью Cython

Задача: Ускорить Python-код с помощью статической типизации.
Промт: «Напиши функцию на Python, которая вычисляет сумму простых чисел до 10⁶. Затем перепиши её на Cython с объявлением типов. Сравни производительность.»
Пример результата:

# sum_primes.pyx
def sum_primes(int limit):
    cdef int i, j, is_prime
    cdef long total = 0
    for i in range(2, limit):
        is_prime = 1
        for j in range(2, i):
            if i % j == 0:
                is_prime = 0
                break
        if is_prime:
            total += i
    return total

Скомпилируй с cythonize и получи ускорение в 10-20 раз.

12. Профилирование асинхронного кода

Задача: Найти узкие места в asyncio-приложении.
Промт: «Напиши асинхронный веб-скрапер, который загружает 100 URL. Используй asyncio и aiohttp. Профилируй с помощью asyncio.profiler и определи, какие корутины блокируют event loop.»
Пример результата:

import asyncio
import aiohttp

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        tasks = [fetch(session, f'http://example.com/{i}') for i in range(100)]
        results = await asyncio.gather(*tasks)

if __name__ == '__main__':
    asyncio.run(main())

Профилирование покажет, что узким местом является сетевой ввод-вывод, а не CPU.

13. Оптимизация с использованием Cython и NumPy

Задача: Создать быстрый численный алгоритм с помощью Cython и NumPy.
Промт: «Напиши функцию на Python, которая выполняет матричное умножение вручную. Затем реализуй её на Cython с использованием типа np.ndarray и объявлением размерностей. Сравни с np.dot
Пример результата:

import numpy as np
cimport numpy as np

def matmul(np.ndarray[np.float64_t, ndim=2] A, np.ndarray[np.float64_t, ndim=2] B):
    cdef int n = A.shape[0], m = B.shape[1], k = A.shape[1]
    cdef np.ndarray[np.float64_t, ndim=2] C = np.zeros((n, m), dtype=np.float64)
    cdef int i, j, l
    for i in range(n):
        for j in range(m):
            for l in range(k):
                C[i, j] += A[i, l] * B[l, j]
    return C

Это даст ускорение в 5-10 раз по сравнению с чистым Python, но всё равно уступит np.dot (который использует BLAS).

14. Оптимизация работы с Numba

Задача: Использовать JIT-компиляцию для ускорения численных вычислений.
Промт: «Напиши функцию на Python, которая вычисляет интеграл методом Монте-Карло. Затем ускорь её с помощью Numba (декоратор @njit). Сравни время выполнения.»
Пример результата:

from numba import njit
import random
import time

@njit
def monte_carlo_pi(n):
    count = 0
    for _ in range(n):
        x = random.random()
        y = random.random()
        if x*x + y*y <= 1:
            count += 1
    return 4 * count / n

start = time.time()
print(monte_carlo_pi(10**7))
print('Numba:', time.time() - start)

Numba ускоряет выполнение в 100-200 раз по сравнению с чистым Python.

15. Оптимизация кэширования с помощью Memcached

Задача: Уменьшить нагрузку на базу данных с помощью распределённого кэширования.
Промт: «Напиши пример использования Memcached для кэширования результатов дорогих запросов к БД. Используй библиотеку pymemcache. Покажи, как измерять hit rate и время ответа.»
Пример результата:

from pymemcache.client import base
import time

client = base.Client(('localhost', 11211))

def get_user_data(user_id):
    cache_key = f'user:{user_id}'
    data = client.get(cache_key)
    if data is None:
        # Долгий запрос к БД
        time.sleep(0.5)  # имитация
        data = {'id': user_id, 'name': 'John'}
        client.set(cache_key, data, expire=3600)
    return data

Это снижает время ответа с 500 мс до 1 мс при наличии кэша.

Заключение

Оптимизация производительности кода — это не разовая акция, а постоянный процесс. Промты помогают автоматизировать рутинные задачи: профилирование, поиск узких мест, сравнение алгоритмов. Начните с базовых примеров, чтобы освоить инструменты вроде timeit и cProfile, затем переходите к продвинутым техникам (Cython, Numba, asyncio). Помните: преждевременная оптимизация — корень всех зол (Дональд Кнут), поэтому всегда измеряйте и профилируйте перед изменениями. Попробуйте применить хотя бы один промт из этой подборки к своему текущему проекту — и вы увидите разницу. Удачи в оптимизации!

← Все статьи

Комментарии

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

Как подготовить бизнес к AI-трансформации: прогнозы 2026 и стратегия внедрения | Курс на Asibiont

19 июля 2026

10 промтов для оптимизации производительности кода

19 июля 2026

12 промтов для Docker: от Dockerfile до multi-stage сборок и оптимизации образов

19 июля 2026

Как автоматизировать криптотрейдинг с интеграцией Coinbase и AI-агентом ASI Biont: руководство без кода для управления портфелем и оповещений в реальном времени

19 июля 2026

Arduino, IoT и встраиваемые системы: с чего начать и как ускорить обучение с AI на Asibiont

19 июля 2026

Codex Resets: как фишка vibe coding меняет подход к разработке в 2026 году

19 июля 2026

MQTT + ASI Biont: AI-агент, который управляет IoT-телеметрией без панелей и дашбордов

19 июля 2026

Как автоматизировать генерацию лидов в LinkedIn с помощью ИИ-агента: руководство без кода с использованием ASI Biont

19 июля 2026

Уголовное право РФ: как за 21 день освоить УК РФ и начать выигрывать дела с помощью AI-обучения

19 июля 2026