Использование Python Timeit для синхронизации вашего кода

Использование Python Timeit для синхронизации вашего кода

В этом руководстве вы узнаете, как использовать функцию timeit из модуля timeit Python. Вы узнаете, как синхронизировать простые выражения и функции в Python.

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

Мы начнем с изучения синтаксиса функции timeit в Python. Далее мы предоставим примеры кода, чтобы понять, как использовать его для синхронизации блоков кода и функций в вашем модуле Python. Давай начнем.

Как использовать функцию timeit Python

Модуль timeit является частью стандартной библиотеки Python, и вы можете импортировать его:

import timeit

Синтаксис использования функции timeit из модуля timeit показан ниже:

timeit.timeit(stmt, setup, number)

здесь:

  • stmt — это фрагмент кода, время выполнения которого необходимо измерить. Вы можете указать его как простую строку Python или многострочную строку или передать имя вызывающей стороны.
  • Как следует из названия, установка указывает на фрагмент кода, который необходимо запустить только один раз, часто в качестве предварительного условия для запуска stmt. Например, предположим, что вы рассчитываете время выполнения для создания массива NumPi. В этом случае импорт numpi — это код установки, а фактическое создание — это оператор, который нужно синхронизировать.
  • Номер параметра указывает, сколько раз запускался stmt. Значение по умолчанию — 1 миллион (1000000), но вы также можете установить для этого параметра любое другое значение по вашему выбору.

Теперь, когда мы изучили синтаксис использования функции timeit(), давайте начнем кодировать несколько примеров.

Временные простые выражения Python

В этом разделе мы попытаемся измерить время выполнения простых выражений Python с помощью timeit.

Запустите Python REPL и выполните следующие примеры кода. Здесь мы вычисляем время выполнения операций возведения в степень и деления пола на 10000 и 100000 ходов.

Обратите внимание, что мы передаем оператор для хронометража в виде строки Python и используем точку с запятой для разделения различных выражений в операторе.

>>> import timeit
>>> timeit.timeit('3**4;3//4',number=10000)
0.0004020999999738706

>>> timeit.timeit('3**4;3//4',number=100000)
0.0013780000000451764

Запуск Python timeit в командной строке

Вы также можете использовать timeit в командной строке. Вот эквивалент командной строки вызова функции timeit:

$ python-m timeit -n [number] -s [setup] [stmt]
  • python -m timeit означает, что мы запускаем timeit как основной модуль.
  • n — это параметр командной строки, который указывает, сколько раз код должен быть запущен. Это эквивалентно числовому аргументу в вызове функции timeit().
  • Вы можете использовать опцию -s для определения кода установки.

Здесь мы перепишем предыдущий пример, используя эквивалент командной строки:

$ python -m timeit -n 100000 '3**4;3//4'
100000 loops, best of 5: 35.8 nsec per loop

В этом примере мы вычисляем время выполнения встроенной функции len(). Строковая инициализация — это код настройки, передаваемый с помощью параметра s.

$ python -m timeit -n 100000 -s "string_1 = 'coding'" 'len(string_1)'
100000 loops, best of 5: 239 nsec per loop

Обратите внимание, что в выводе мы получаем время выполнения для лучшего из 5 запусков. Что это значит? Когда вы запускаете timeit из командной строки, параметру повторения r присваивается значение по умолчанию, равное 5. Это означает, что выполнение stmt указанное количество раз повторяется пять раз, и возвращается лучшее время выполнения.

Анализ методов обращения строк с использованием timeit

При работе со строками Python вы можете захотеть обратить их. Два наиболее распространенных подхода к обращению строк следующие:

  • Использование струнной резки
  • Использование функции reversed() и метода join().

Обратные строки Python с использованием обрезки строк

Давайте рассмотрим, как работает нарезка строк и как вы можете использовать ее для реверсирования строки Python. Использование синтаксиса некоторых строк[start:stop] возвращает часть строки, начинающуюся с начала индекса и доходящую до индекса stop-1. Возьмем пример.

Рассмотрим следующую строку «Python». Массив имеет длину 6, а список индексов — от 0, 1, 2 до 5.

>>> string_1 = 'Python'

Когда вы указываете как начальное, так и предельное значение, вы получаете фрагмент строки, который простирается от начала до конца-1. Следовательно, строка_1[1:4] возвращает «ит».

>>> string_1 = 'Python'
>>> string_1[1:4]
'yth'

Когда вы не указываете начальное значение, используется начальное значение по умолчанию, равное нулю, и перехват начинается с нулевого индекса и продолжается до конца — 1.

Здесь конечное значение равно 3, поэтому срез начинается с индекса 0 и переходит к индексу 2.

>>> string_1[:3]
'Pyt'

Если вы не укажете конечный индекс, вы увидите, что фрагмент начинается с начального индекса (1) и продолжается до конца строки.

>>> string_1[1:]
'ython'

Игнорирование как начального, так и предельного значений возвращает часть всей строки.

>>> string_1[::]
'Python'

Создадим сниппет со значением шага. Установите значения запуска, остановки и шага на 1, 5 и 2 соответственно. Мы получаем часть строки, начинающуюся с 1 и доходящую до 4 (исключая конечную точку 5), содержащую все остальные символы.

>>> string_1[1:5:2]
'yh'

Когда вы используете отрицательный шаг, вы можете получить клип, который начинается в конце строки. С шагом, установленным на -2, string_1[5:2:-2] дает следующую часть:

>>> string_1[5:2:-2]
'nh'

Итак, чтобы получить обратную копию строки, мы пропускаем начальное и конечное значения и устанавливаем шаг равным -1, как показано:

>>> string_1[::-1]
'nohtyP'

Короче: строка[::-1] возвращает обратную копию строки.

Обратное преобразование строк с помощью встроенных строковых функций и методов.

Встроенная функция Python reversed() возвращает обратный итератор для элементов строки.

>>> string_1 = 'Python'
>>> reversed(string_1)

Таким образом, вы можете пройти через обратный итератор, используя цикл for:

for char in reversed(string_1):
    print(char)

И обращаться к элементам массива в обратном порядке.

# Output
n
o
h
t
y
P

Затем вы можете вызвать метод join() для обратного итератора с синтаксисом: .join(reversed(some-string)).

Фрагмент кода ниже показывает несколько примеров, где разделителем является тире и пробел соответственно.

>>> '-'.join(reversed(string1))
'n-o-h-t-y-P'
>>> ' '.join(reversed(string1))
'n o h t y P'

Здесь нам не нужен разделитель; поэтому установите разделитель на пустую строку, чтобы получить обратную копию строки:

>>> ''.join(reversed(string1))
'nohtyP'

Использование .join(reversed(some-string)) возвращает обратную копию строки.

Сравнение времени выполнения Использование timeit

До сих пор мы изучили два подхода к обращению строк Python. Но какой из них быстрее? Давай выясним.

В предыдущем примере, где мы измеряли время простых выражений Python, у нас не было кода установки. Здесь мы переворачиваем строку Python. В то время как операция обращения строки выполняется столько раз, сколько указано числом, код установки представляет собой инициализацию строки, которая будет запущена только один раз.

>>> import timeit
>>> timeit.timeit(stmt="string_1[::-1]", setup = "string_1 = 'Python'", number = 100000)
0.04951830000001678
>>> timeit.timeit(stmt = "''.join(reversed(string_1))", setup = "string_1 = 'Python'", number = 100000)
0.12858760000000302

При том же количестве прогонов для реверсирования заданной строки метод обрезки строки быстрее, чем использование метода join() и функции reversed().

Функции времени Python с использованием timeit

В этом разделе мы узнаем, как измерять функции Python с помощью функции timeit. При наличии списка строк следующая функция hasDigit возвращает список строк, содержащих хотя бы одну цифру.

def hasDigit(somelist):
     str_with_digit = []
     for string in somelist:
         check_char = [char.isdigit() for char in string]
         if any(check_char):
            str_with_digit.append(string)
     return str_with_digit

Теперь мы хотели бы измерить время выполнения этой функции Python hasDigit() с помощью timeit.

Давайте сначала определим оператор, который будет синхронизирован (stmt). Это вызов функции hasDigit() со списком строк в качестве аргумента. Далее давайте определим код установки. Можете ли вы угадать, каким должен быть код установки?

Для успешного выполнения вызова функции код установки должен содержать следующее:

  • Определение функции hasDigit()
  • Инициализация списка строковых аргументов

Давайте определим код установки в строке установки, как показано ниже:

setup = """
def hasDigit(somelist):
    str_with_digit = []
    for string in somelist:
      check_char = [char.isdigit() for char in string]
      if any(check_char):
        str_with_digit.append(string)
    return str_with_digit
thislist=['puffin3','7frost','blue']
     """

Затем мы можем использовать функцию timeit и получить время выполнения функции hasDigit() для 100000 запусков.

import timeit
timeit.timeit('hasDigit(thislist)',setup=setup,number=100000)
# Output
0.2810094920000097

Заключение

Вы узнали, как использовать функцию Python timeit для определения времени выражений, функций и других вызовов. Это может помочь вам сравнить свой код, сравнить время выполнения различных реализаций одной и той же функции и многое другое.

Давайте повторим, что мы узнали из этого руководства. Вы можете использовать функцию timeit() с синтаксисом timeit.timeit(stmt=…,setup=…,number=…). В качестве альтернативы вы можете запустить timeit в командной строке, чтобы синхронизировать короткие фрагменты кода.

В качестве следующего шага вы можете изучить, как использовать другие пакеты профилирования Python, такие как line-profiler и memprofiler, для профилирования кода по времени и памяти соответственно.

Далее узнайте, как рассчитать разницу во времени в Python.

Поделиться в соцсетях