← Назад к вопросам
Какие знаешь инструменты оптимизации Python кода?
1.7 Middle🔥 211 комментариев
#REST API и HTTP
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Инструменты оптимизации Python кода
Оптимизация — это процесс выявления узких мест и ускорения критичного кода. Вот практические инструменты которые я использую.
1. Profiling с cProfile
Выявляет какие функции занимают больше всего времени:
import cProfile
import pstats
def slow_function():
result = 0
for i in range(1000000):
result += i ** 2
return result
# Профилирование
profiler = cProfile.Profile()
profiler.enable()
slow_function()
profiler.disable()
# Вывод результатов
stats = pstats.Stats(profiler)
stats.sort_stats('cumulative')
stats.print_stats()
Вывод:
ncalls tottime percall cumtime percall filename:lineno
1 0.150 0.150 0.150 0.150 script.py:3
2. Line Profiler (line_profiler)
Профилирует каждую строку кода:
pip install line_profiler
# script.py
from line_profiler import profile
@profile
def function_to_optimize():
result = 0 # Строка 1
for i in range(1000000): # Строка 2
result += i ** 2 # Строка 3
return result # Строка 4
function_to_optimize()
kernprof -l -v script.py
Вывод:
Line # Hits Time Per Hit % Time Line Contents
4 def function_to_optimize():
5 1 100.0 100.0 50.0 result = 0
6 1000001 200.0 0.0 50.0 for i in range(1000000):
7 1000000 300.0 0.0 100.0 result += i ** 2
3. Memory Profiler (memory_profiler)
Выявляет утечки памяти:
pip install memory_profiler
from memory_profiler import profile
@profile
def create_list():
x = [i for i in range(1000000)] # Много памяти
return x
create_list()
python -m memory_profiler script.py
4. Timing с timeit
Для быстрого сравнения альтернатив:
import timeit
# Способ 1: list comprehension
code1 = '[i*2 for i in range(1000)]'
# Способ 2: map
code2 = 'list(map(lambda i: i*2, range(1000)))'
time1 = timeit.timeit(code1, number=10000)
time2 = timeit.timeit(code2, number=10000)
print(f"List comprehension: {time1:.4f}s")
print(f"Map: {time2:.4f}s")
print(f"Speedup: {time2/time1:.2f}x")
5. Cython для критичного кода
Переводит Python в C для ускорения:
# fib.pyx (Cython)
def fibonacci(int n):
cdef int a, b
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
pip install cython
cythonize -i fib.pyx
python -c "from fib import fibonacci; print(fibonacci(100))"
Результат: 1000x быстрее!
6. NumPy для работы с данными
Для массивов NumPy на 100x быстрее чем Python:
import numpy as np
# ПЛОХО: Python loop
result = 0
for i in range(1000000):
result += i ** 2
# ХОРОШО: NumPy (моментально)
result = np.arange(1000000) ** 2
result = result.sum()
7. Numba для JIT компиляции
Автоматическая компиляция в машинный код:
from numba import jit
@jit(nopython=True) # JIT компиляция
def sum_of_squares(n):
result = 0
for i in range(n):
result += i ** 2
return result
sum_of_squares(1000000) # Работает как C
8. Database Query Optimization
# ПЛОХО: N+1 query
users = User.objects.all()
for user in users: # 1 запрос
print(user.profile.age) # N запросов
# ХОРОШО: JOIN через select_related
users = User.objects.select_related('profile').all()
for user in users: # 1 запрос вместо N+1
print(user.profile.age)
9. Caching стратегии
from functools import lru_cache
# LRU Cache для функций
@lru_cache(maxsize=128)
def expensive_calculation(n):
return sum(i ** 2 for i in range(n))
expensive_calculation(1000) # Вычисляет
expensive_calculation(1000) # Использует кеш
# Redis для распределённого кеша
import redis
client = redis.Redis()
def cached_db_query(user_id):
# Проверяем кеш
cached = client.get(f'user:{user_id}')
if cached:
return json.loads(cached)
# Запрашиваем БД
user = User.objects.get(id=user_id)
# Кешируем на 1 час
client.setex(
f'user:{user_id}',
3600,
json.dumps(user.to_dict())
)
return user.to_dict()
10. Lazy Loading и Generators
Обработка больших датасетов без загрузки в память:
# ПЛОХО: загружает всё в память
def read_file(filename):
with open(filename) as f:
return f.readlines() # Весь файл в памяти!
# ХОРОШО: generator (на лету)
def read_file(filename):
with open(filename) as f:
for line in f:
yield line.strip() # По строке за раз
# Использование
for line in read_file('huge_file.txt'):
process(line)
11. Асинхронность с asyncio
Параллельная обработка I/O операций:
import asyncio
import aiohttp
# ПЛОХО: синхронные запросы
for url in urls:
response = requests.get(url) # Ждём каждый запрос
process(response)
# ХОРОШО: асинхронные запросы
async def fetch_all(urls):
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, url) for url in urls]
return await asyncio.gather(*tasks)
async def fetch_url(session, url):
async with session.get(url) as response:
return await response.json()
asyncio.run(fetch_all(urls))
12. Compilation и Optimization Flags
# Optimize imports
python -O script.py # Удаляет assert и __debug__
# Compile to bytecode
python -m compileall .
# PyPy для быстрого выполнения
pip install pypy3
pypy3 script.py # Может быть 5-10x быстрее!
13. Algoritm Optimization
Лучший алгоритм > любая оптимизация:
# ПЛОХО: O(n²)
def find_duplicates(numbers):
for i in range(len(numbers)):
for j in range(i + 1, len(numbers)):
if numbers[i] == numbers[j]:
return True
return False
# ХОРОШО: O(n)
def find_duplicates(numbers):
seen = set()
for num in numbers:
if num in seen:
return True
seen.add(num)
return False
Чеклист оптимизации
Шаг 1: Profiling
- Запусти cProfile на production данных
- Выявь Top-5 медленных функций
- Используй memory_profiler для утечек
Шаг 2: Database
- Используй select_related/prefetch_related
- Добавь индексы
- Кешируй часто запрашиваемые данные
Шаг 3: Algorithm
- Проверь сложность O(n)
- Используй правильные структуры данных
- Избегай loop inside loop
Шаг 4: Code
- Используй list comprehension вместо loops
- Кешируй функции (lru_cache)
- Используй generators для больших датасетов
Шаг 5: Deployment
- Используй PyPy если возможно
- Кешируй с Redis
- Используй CDN для статики
- Используй async для I/O операций
Правило: профилируй перед оптимизацией, не угадывай!