Найди узкое место в медленном Python-коде по данным профиля и предложи правку.
Код (свой вставь вместо примера):
[КОД: def report(rows):
out = []
for r in rows:
client = db.query("SELECT name FROM clients WHERE id=%s", r.client_id)
total = sum(o.amount for o in db.query("SELECT * FROM orders WHERE client_id=%s", r.client_id))
out.append({'name': client.name, 'total': total})
return sorted(out, key=lambda x: -x['total'])]
Вывод профиля:
[ПРОФИЛЬ: ncalls 12000 tottime 0.412 cumtime 38.940 db.query; ncalls 6000 tottime 0.088 cumtime 39.210 report; ncalls 6000 tottime 0.031 cumtime 0.031 sorted]
Условия запуска: [УСЛОВИЯ: 6 000 строк на вход, вызывается раз в час, сейчас 39 секунд, надо уложиться в 5]
Что нужно:
1. Три главных узких места по cumulative time, с числами из профиля.
2. Для каждого — причина по существу: N+1 к базе, лишние аллокации, неверный алгоритм, ожидание сети,
блокировка интерпретатора.
3. Правка кодом «было → стало» для каждого места.
4. Ожидаемое время после правки, посчитанное из чисел профиля, а не «станет намного быстрее».
5. Что замерить повторно, чтобы подтвердить.
Отсечка. Не давай советов, которые не подтверждаются профилем: «используйте numpy», «добавьте
кеширование», «перепишите на asyncio» без опоры на cumtime — это угадывание. Не оптимизируй то,
у чего tottime тысячные доли секунды: sorted в примере трогать бессмысленно, сколько бы он ни
раздражал. Если из профиля не видно, где время, скажи прямо, какой замер нужно добавить.
Проверка перед выдачей: сложи ожидаемую экономию по всем правкам и сверь с целевым временем
из условий. Если суммарно цель не достигается, так и напиши, а не подгоняй оценку.