Декоратор, который профилирует вызов метода и регистрирует результат профилирования

Я хочу создать декоратор, который профилирует метод и регистрирует результат. Как это может быть сделано?

3 Solutions collect form web for “Декоратор, который профилирует вызов метода и регистрирует результат профилирования”

Декоратор будет выглядеть примерно так:

import time import logging def profile(func): def wrap(*args, **kwargs): started_at = time.time() result = func(*args, **kwargs) logging.info(time.time() - started_at) return result return wrap @profile def foo(): pass 

В любом случае, если вы хотите сделать серьезное профилирование, я бы предложил вам использовать профили или пакеты cProfile.

Если вы хотите правильно профилировать вместо времени, вы можете использовать недокументированную функцию cProfile (из этого вопроса ):

 import cProfile def profileit(func): def wrapper(*args, **kwargs): datafn = func.__name__ + ".profile" # Name the data file sensibly prof = cProfile.Profile() retval = prof.runcall(func, *args, **kwargs) prof.dump_stats(datafn) return retval return wrapper @profileit def function_you_want_to_profile(...) ... 

Если вы хотите больше контролировать имя файла, вам понадобится еще один слой косвенности:

 import cProfile def profileit(name): def inner(func): def wrapper(*args, **kwargs): prof = cProfile.Profile() retval = prof.runcall(func, *args, **kwargs) # Note use of name from outer scope prof.dump_stats(name) return retval return wrapper return inner @profileit("profile_for_func1_001") def func1(...) ... 

Это выглядит сложным, но если вы будете следовать ему шаг за шагом (и обратите внимание на разницу в вызове профилировщика), он должен стать ясным.

Здесь находится декоратор с двумя параметрами, имя файла профиля и поле для сортировки по результатам. Значение по умолчанию – это кумулятивное время, которое полезно для поиска узких мест.

 def profileit(prof_fname, sort_field='cumtime'): """ Parameters ---------- prof_fname profile output file name sort_field "calls" : (((1,-1), ), "call count"), "ncalls" : (((1,-1), ), "call count"), "cumtime" : (((3,-1), ), "cumulative time"), "cumulative": (((3,-1), ), "cumulative time"), "file" : (((4, 1), ), "file name"), "filename" : (((4, 1), ), "file name"), "line" : (((5, 1), ), "line number"), "module" : (((4, 1), ), "file name"), "name" : (((6, 1), ), "function name"), "nfl" : (((6, 1),(4, 1),(5, 1),), "name/file/line"), "pcalls" : (((0,-1), ), "primitive call count"), "stdname" : (((7, 1), ), "standard name"), "time" : (((2,-1), ), "internal time"), "tottime" : (((2,-1), ), "internal time"), Returns ------- None """ def actual_profileit(func): def wrapper(*args, **kwargs): prof = cProfile.Profile() retval = prof.runcall(func, *args, **kwargs) stat_fname = '{}.stat'.format(prof_fname) prof.dump_stats(prof_fname) print_profiler(prof_fname, stat_fname, sort_field) print('dump stat in {}'.format(stat_fname)) return retval return wrapper return actual_profileit def print_profiler(profile_input_fname, profile_output_fname, sort_field='cumtime'): import pstats with open(profile_output_fname, 'w') as f: stats = pstats.Stats(profile_input_fname, stream=f) stats.sort_stats(sort_field) stats.print_stats() 
  • Оптимизация для PyPy
  • Как измерить время между строками кода в python?
  • Почему два алгоритма для нахождения простых чисел отличаются скоростью настолько, что, похоже, они выполняют одинаковое количество итераций?
  • Как определить длинные блокирующие функции в приложении Tornado
  • Есть ли визуальный профилировщик для Python?
  • Что такое «встроенный метод» Python? Как я могу ускорить его?
  • Профилирование python с использованием line_profiler - умный способ удаления операторов @profile на лету?
  • Что это за результат cProfile, говорящий мне, что мне нужно исправить?
  •  
    Interesting Posts for Van-Lav

    Почему декораторы Python синтаксически отличаются от аргументов без них?

    Форма django получила несколько значений для аргумента ключевого слова

    в Numpy, как закрепить два двухмерных массива?

    фатальная ошибка: файл QTKit / QTKit.h не найден, когда я создаю OpenCV на mac

    WSGI Middleware для аутентификации OAuth

    Является ли web2py подходящим для большого общедоступного веб-сайта?

    Python: lxml xpath получает два разных класса

    пифонический формат для индексов

    В чем разница между методами len () и sys.getsizeof () в python?

    Есть ли многозначительный biginteger?

    Python Pandas Dataframe выбрать строку по максимальному значению в группе

    Является ли python достаточно умным, чтобы заменить вызовы функций постоянным результатом?

    Передача stdout из ноутбука Jupyter приземляется в терминале

    Python – Скремблирование экрана и управление мышью в OS X

    Django DateTimeField TypeError: ожидаемая строка или байтоподобный объект

    Python - лучший язык программирования в мире.