19 апреля 2013 г.

Альтернативные реализации модуля хронометража

Сегодня пятница, пора постить новый урок по программированию на Python.
Появилась новая страница в блоге, на нее не обращайте внимание, это для сэо.

Значит так, урок начинается....

Сегодня рассмотрим альтернативную реализацию модуля хронометража (смотреть предыдущий пост).

Примитивность,минуса предыдущего модуля хронометража с предыдущего поста:

  • В  нем  всегда  используется  функция  time.clock.  В  операционной  системе Windows она является лучшим выбором, однако на платформах в системе UNIX более высокую точность можно получить с помощью функции time.time.

  • Для  изменения  количества  повторений  требуется  изменять  глобальную переменную модуля – не самое идеальное решение, если функция timer импортируется и одновременно используется в нескольких модулях.

  • Функция timer выполняет  тестовую функцию  большое число  раз.  Чтобы учесть случайные флуктуации, вызванные различными уровнями нагрузки на  систему,  можно было бы отбирать  наилучшие результаты  из  серии тестов вместо того, чтобы рассчитывать общее время выполнения.



Ниже приводится более сложная, альтернативная реализация модуля mytimer.
Плюсы в нем будут, это:
- Выбор функции определения времени под определенную платформу;
- Счетчик повторений передается функции timer в виде именованного аргумента  _reps и дополнительно  предоставляется функция хронометража.
- Возвращающая лучший результат из серии по N испытаниям.

# Файл mytimer.py (2.6 и 3.0)
“””
timer(spam, 1, 2, a=3, b=4, _reps=1000) вызывает и измеряет время работы функции 
spam(1, 2, a=3) _reps раз, и возвращает общее время, затраченное на все вызовы, 
с результатом вызова испытуемой функции;

best(spam, 1, 2, a=3, b=4, _reps=50) многократно вызывает функцию timer, чтобы 
исключить влияние флуктуаций в нагрузке на систему, и возвращает лучший результат из 
серии по _reps испытаниям
“””

import time, sys
if sys.platform[:3] == ‘win’:
    timefunc = time.clock            # В Windows использовать time.clock 
else:
    timefunc = time.time             # На некоторых платформах Unix дает 
                                     # лучшее разрешение

def trace(*args): pass               # Заглушка: вывод аргументов

def timer(func, *pargs, **kargs):
    _reps = kargs.pop(‘_reps’, 1000) # Полученное число повторов 
                                     # или значение по умолчанию
    trace(func, pargs, kargs, _reps)
    repslist = range(_reps)# Вызов range вынесен за пределы 
                           # цикла for для версии 2.6
    start = timefunc()
    for i in repslist:
        ret = func(*pargs, **kargs)
    elapsed = timefunc() - start
    return (elapsed, ret)

def best(func, *pargs, **kargs):
    _reps = kargs.pop(‘_reps’, 50)
    best = 2 ** 32
    for i in range(_reps):
         (time, ret) = timer(func, *pargs, _reps=1, **kargs)
        if time < best: best = time
    return (best, ret)

Используется  метод  pop  словарей,  чтобы  удалить  аргумент _reps из списка аргументов.
Модуль позволяет выводить значения аргументов на этапе отладки, для чего достаточно заменить функцию trace функцией print.



Комментариев нет:

Отправить комментарий