Как измерить потребление ресурсов решения
Что проверяют
Умеете ли вы отделить время от памяти и оценку на бумаге от замера. Часто вопрос звучит после задачи на алгоритм: сначала хотят услышать асимптотику, потом как вы подтвердите её цифрами. Следом спрашивают, как найти функцию, которая съедает ресурсы.
Как отвечать
Начните с оценки сложности по времени и памяти, а затем назовите инструменты под каждую метрику:
- время:
time.perf_counter()для интервалов,time.process_time()для чистого CPU без ожидания ввода-вывода,timeitдля микробенчмарков с многократным повтором; - где тратится CPU:
cProfileс разбором черезpstatsили snakeviz,line_profilerдля построчного разбора горячей функции; - сэмплирующие профилировщики:
py-spyподключается к работающему процессу без правки кода и почти не замедляет его,scaleneпоказывает CPU и память построчно; - память Python-объектов:
tracemallocсо снимками до и после и сравнением черезcompare_to,memrayдля поиска утечек и пиков, включая аллокации в C-расширениях; - процесс целиком:
psutil.Process().memory_info().rssиcpu_times(), пиковое потребление черезresource.getrusage(...).ru_maxrss.
Замер повторяйте несколько раз, отбрасывайте прогрев, берите медиану и гоняйте на данных реального размера. Для сервиса добавьте метрики в продакшене, например клиент Prometheus и дашборд, иначе вы оптимизируете лабораторный сценарий.
Где спотыкаются
Меряют time.time(). Это настенные часы, их может подвинуть синхронизация времени, для интервалов нужен монотонный perf_counter.
Сравнивают ru_maxrss до и после функции как расход памяти. Это пик за всю жизнь процесса, а не текущее значение, и единицы разные: на Linux килобайты, на macOS байты.
Верят первому вызову psutil.cpu_percent() без интервала: он возвращает бессмысленный 0.0, сравнивать ему ещё не с чем. И забывают, что cProfile сам замедляет код с множеством мелких вызовов и искажает картину.