Использование Python Timeit для тайминга вашего кода

Опубликовано: 2023-01-17

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

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

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

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

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

 import timeit

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

 timeit.timeit(stmt, setup, number)

Здесь:

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

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

Синхронизация простых выражений Python

Синхронизация простых выражений 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 — это параметр командной строки, обозначающий, сколько раз должен запускаться код. Это эквивалентно number аргументу в вызове функции 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 из командной строки, параметру repeat r присваивается значение по умолчанию , равное 5. Это означает, что выполнение stmt указанное number раз повторяется пять раз, и возвращается лучшее время выполнения.

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

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

  • Использование нарезки строк
  • Использование функции reversed() и метода join()
Анализ-методов-обращения-строки-использование-timeit

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

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

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

изображение-76
 >>> string_1 = 'Python'

Когда вы указываете как start , так и stop значения, вы получаете фрагмент строки, который простирается от start до stop-1 . Поэтому string_1[1:4] возвращает 'yth'.

изображение-77
 >>> string_1 = 'Python' >>> string_1[1:4] 'yth'

Когда вы не указываете start значение, используется start значение по умолчанию, равное нулю, и срез начинается с нулевого индекса и расширяется до stop - 1 .

изображение-78

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

 >>> string_1[:3] 'Pyt'

Когда вы не включаете stop индекс, вы видите, что срез начинается с start индекса (1) и продолжается до конца строки.

изображение-80
 >>> string_1[1:] 'ython'

Игнорирование start и stop значений возвращает фрагмент всей строки.

изображение-81
 >>> string_1[::] 'Python'

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

изображение-82
 >>> string_1[1:5:2] 'yh'

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

изображение-83
 >>> string_1[5:2:-2] 'nh'

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

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

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

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

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

 >>> string_1 = 'Python' >>> reversed(string_1) <reversed object at 0x00BEAF70>

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

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

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

 # Output n o h t y P

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

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

 >>> '-'.join(reversed(string1)) 'nohtyP' >>> ' '.join(reversed(string1)) 'nohty P'

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

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

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

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

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

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

 >>> 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

В этом разделе мы узнаем, как измерять время функций 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() со списком строк в качестве аргумента. Далее давайте определим код установки . Можете ли вы угадать, каким должен быть код setup ?

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

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

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

 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.