Найди узкое место в медленном 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 в примере трогать бессмысленно, сколько бы он ни
раздражал. Если из профиля не видно, где время, скажи прямо, какой замер нужно добавить.
Проверка перед выдачей: сложи ожидаемую экономию по всем правкам и сверь с целевым временем
из условий. Если суммарно цель не достигается, так и напиши, а не подгоняй оценку.
Собрать под себя — поля заполнены рабочими значениями, меняйте их и промпт выше обновится сам
Топ-3 bottleneck:
1. _build_users_list (4.2s / 80%)
Причина: N+1 запрос — для каждого user отдельный SQL к profile. 1000 users × 5ms = 5s.
Было: for u in users: u.profile = db.get_profile(u.id)
Стало: profiles = db.get_profiles_by_ids([u.id for u in users]) # один JOIN-запрос
Ускорение: ~30x (с 5s до ~150ms)
2. json.dumps (0.5s / 10%)
Причина: стандартный json медленнее orjson в 3-5 раз.
Фикс: orjson.dumps(data). Ускорение: ~4x.