Использование 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а фактическое создание — это оператор, который должен быть рассчитан по времени. - Номер параметра обозначает
numberstmt. Значениеnumberпо умолчанию — 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— это параметр командной строки, обозначающий, сколько раз должен запускаться код. Это эквивалентно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()

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

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

>>> string_1 = 'Python' >>> string_1[1:4] 'yth' Когда вы не указываете start значение, используется start значение по умолчанию, равное нулю, и срез начинается с нулевого индекса и расширяется до stop - 1 .

Здесь stop значение равно 3, поэтому срез начинается с индекса 0 и поднимается до индекса 2.
>>> string_1[:3] 'Pyt' Когда вы не включаете stop индекс, вы видите, что срез начинается с start индекса (1) и продолжается до конца строки.

>>> string_1[1:] 'ython' Игнорирование start и stop значений возвращает фрагмент всей строки.


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

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

>>> 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. При наличии списка строк следующая функция 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.
