Декоратор для измерения времени выполнения функции

Этот декоратор добавляет прошедшее время к атрибутам функции при применении.

Мои проблемы:

  • Является ли код pythonic?
  • Может ли этот код быть полезным?
  • Должен ли я просто использовать модуль timeit?
  • Легко ли читать и понимать код?

Код:

'''
:Date: 7/21/17
:Version: 1
:Authors:
    - Ricky L Wilson
'''


import datetime

def time_func(function):
  """ This decorator calculates the amount of time a function takes to execute.

  When time_func is applied to a function it records how long the function takes to
  finish and add the elapsed time to the functions attributes.

  - **parameters**
  :param function: The function you want to add the elapsed time attribute to.

  :Example:
  @time_func  
  def example(name, **kwargs):
    meta = type(name, (object,), kwargs)
    return meta

  example('foo')
  print example.elapsed
  0:00:00.000052

  """
  def new_func(*args, **kwargs):
    # Start the clock.
    start = datetime.datetime.now()
    # Execute the function and record the results.
    function_result = function(*args, **kwargs)
    # Calculate the elapsed time and add it to the function
    # attributes.
    new_func.elapsed = datetime.datetime.now() - start
    # Returned the function with the added elapsed attribute 
    return function_result
  return new_func
8 голосов | спросил Ricky Wilson 21 J000000Friday17 2017, 21:24:27

1 ответ


12

Я бы рекомендовал timeit при измерении времени выполнения функций. AFAIK, timeit отключает сборщик мусора на время теста, что может дать лучшие результаты в целом.

Из здесь :

  

timeit более точен по трем причинам:

     
  • повторяет тесты много раз, чтобы исключить влияние других задач на вашем компьютере, таких как очистка диска и планирование ОС.
  •   
  • он отключает сборщик мусора, чтобы этот процесс не искажал результаты, планируя запуск коллекции в неподходящий момент   момент.
  •   
  • он выбирает самый точный таймер для вашей ОС, time.time или time.clock, см.    timeit.default_timer
  •   

С другой стороны, декоратор времени действительно полезен, потому что вы можете использовать аннотации, чтобы посыпать время вокруг вашего кода, а не повредить ваш код с логикой синхронизации. Так что да, связанный с одним из ваших вопросов, код полезен.

Теперь, на вопрос pythonic , IMO:

  • у вас слишком много комментариев, которые, к сожалению, не добавили никакой ценности для вашего кода. Удалите их.
  • Ваша внутренняя функция также может быть переименована в нечто более интуитивное, например wrapper.
  • function также не лучший выбор, когда речь идет о соглашениях об именах, поскольку это может затенять встроенный function
  • используйте две новые строки между импортом и методами.
  • отступ должен быть кратным 4 (пробелам)
  • используйте тройные двойные кавычки для вашего документа docstring

В Python уже есть некоторые полезные модули, которые помогут вам в этом. Например, в functools у вас есть wraps decorator. Это принимает функцию, используемую в декораторе, и добавляет функции копирования по имени функции, docstring, списку аргументов и т. Д. И поскольку wraps сам по себе декоратор, я думаю, это упростит ситуацию.


Код:

from functools import wraps
from time import time


def timing(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        start = time()
        result = f(*args, **kwargs)
        end = time()
        print 'Elapsed time: {}'.format(end-start)
        return result
    return wrapper

Применение:

@timing
def f(a):
    for _ in range(a):
        pass

print(f(2000000))

Результат:

  

Elapsed time: 0.0971460342407

ответил яүυк 21 J000000Friday17 2017, 22:22:07

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132