timeit.md
1> **Источник:** https://python-all.ru/3.0/library/timeit.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `timeit` – Измерение времени выполнения небольших фрагментов кода89Этот модуль предоставляет простой способ измерения времени выполнения небольших фрагментов кода Python. Он имеет как интерфейс командной строки, так и вызываемый интерфейс. Он позволяет избежать ряда распространённых ловушек при измерении времени выполнения. См. также введение Тима Питерса в главу «Алгоритмы» в книге Python Cookbook, опубликованной O’Reilly.1011Модуль определяет следующий открытый класс:1213#### `[timeit.Timer]class timeit.Timer([stmt='pass'[, setup='pass'[, timer=<timer function>]]])`1415Класс для измерения скорости выполнения небольших фрагментов кода.1617Конструктор принимает измеряемый оператор, дополнительный оператор для настройки и функцию таймера. Оба оператора по умолчанию равны `'pass'`; функция таймера зависит от платформы (см. строку документации модуля). Операторы могут содержать символы новой строки, если они не содержат многострочные строковые литералы.1819Для измерения времени выполнения первого оператора используйте метод [`timeit()`](https://python-all.ru/3.0/library/timeit.html#timeit.timeit). Метод [`repeat()`](https://python-all.ru/3.0/library/timeit.html#timeit.repeat) – это удобная функция для вызова [`timeit()`](https://python-all.ru/3.0/library/timeit.html#timeit.timeit) несколько раз и возврата списка результатов.2021Параметры *stmt* и *setup* также могут принимать вызываемые объекты без аргументов. Это встраивает вызовы к ним в функцию таймера, которая затем выполняется с помощью [`timeit()`](https://python-all.ru/3.0/library/timeit.html#timeit.timeit). Обратите внимание, что в этом случае накладные расходы на измерение времени немного выше из-за дополнительных вызовов функций.2223#### `[timeit.Timer.print_exc]Timer.print_exc([file=None])`2425Вспомогательная функция для вывода трассировки из кода, время выполнения которого измеряется.2627Типичное использование:2829```python30t = Timer(...) # за пределами try/except31try:32 t.timeit(...) # или t.repeat(...)33except:34 t.print_exc()35```3637Преимущество перед стандартным traceback в том, что будут отображаться строки исходного кода в скомпилированном шаблоне. Необязательный аргумент *file* определяет, куда отправляется traceback; по умолчанию он отправляется в `sys.stderr`.3839#### `[timeit.Timer.repeat]Timer.repeat([repeat=3[, number=1000000]])`4041Вызывает [`timeit()`](https://python-all.ru/3.0/library/timeit.html#timeit.timeit) несколько раз.4243Это удобная функция, которая многократно вызывает [`timeit()`](https://python-all.ru/3.0/library/timeit.html#timeit.timeit), возвращая список результатов. Первый аргумент указывает, сколько раз вызывать [`timeit()`](https://python-all.ru/3.0/library/timeit.html#timeit.timeit). Второй аргумент задаёт значение параметра *number* для [`timeit()`](https://python-all.ru/3.0/library/timeit.html#timeit.timeit).4445> **Примечание**46>47> Может возникнуть соблазн вычислить среднее и стандартное отклонение из вектора результатов и сообщить их. Однако это не очень полезно. В типичном случае наименьшее значение даёт нижнюю границу того, насколько быстро ваша машина может выполнить данный фрагмент кода; более высокие значения в векторе результатов обычно вызваны не изменчивостью скорости Python, а другими процессами, мешающими точности измерения времени. Поэтому [`min()`](https://python-all.ru/3.0/library/functions.html#min) результатов – вероятно, единственное число, которое вас должно интересовать. После этого следует посмотреть на весь вектор и применить здравый смысл, а не статистику.4849#### `[timeit.Timer.timeit]Timer.timeit([number=1000000])`5051Измеряет время выполнения *number* повторений основного оператора. Он выполняет оператор настройки один раз, а затем возвращает время, необходимое для выполнения основного оператора заданное число раз, измеряемое в секундах как число с плавающей запятой. Аргумент – это количество повторений цикла, по умолчанию один миллион. Основной оператор, оператор настройки и используемая функция таймера передаются конструктору.5253> **Примечание**54>55> По умолчанию [`timeit()`](https://python-all.ru/3.0/library/timeit.html#timeit.timeit) временно отключает [*сборку мусора*](https://python-all.ru/3.0/glossary.html#term-garbage-collection) во время измерения времени. Преимущество такого подхода в том, что он делает независимые измерения более сопоставимыми. Недостаток в том, что сборка мусора может быть важной составляющей производительности измеряемой функции. Если это так, сборку мусора можно снова включить, указав её в качестве первого оператора в строке *setup*. Например:56>57> ```python58> timeit.Timer('for i in range(10): oct(i)', 'gc.enable()').timeit()59> ```6061Модуль также определяет две вспомогательные функции:6263#### `[timeit.repeat]timeit.repeat(stmt[, setup[, timer[, repeat=3[, number=1000000]]]])`6465Создаёт экземпляр6667[`Timer`](https://python-all.ru/3.0/library/timeit.html#timeit.Timer)6869с указанным оператором, кодом настройки и функцией таймера и запускает его метод7071[`repeat()`](https://python-all.ru/3.0/library/timeit.html#timeit.repeat)7273с заданным количеством повторений и7475*number*7677выполнениями.7879#### `[timeit.timeit]timeit.timeit(stmt[, setup[, timer[, number=1000000]]])`8081Создаёт экземпляр8283[`Timer`](https://python-all.ru/3.0/library/timeit.html#timeit.Timer)8485с указанным оператором, кодом настройки и функцией таймера и запускает его метод8687[`timeit()`](https://python-all.ru/3.0/library/timeit.html#timeit.timeit)8889с9091*number*9293выполнениями.9495## Интерфейс командной строки9697При вызове как программы из командной строки используется следующая форма:9899```python100python -m timeit [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement ...]101```102103где принимаются следующие опции:104105**-n N/*--number=N***106107сколько раз выполнять 'statement'108109**-r N/*--repeat=N***110111сколько раз повторять таймер (по умолчанию 3)112113**-s S/*--setup=S***114115оператор, который будет выполнен один раз в начале (по умолчанию116117`'pass'`118119)120121**-t/*--time***122123использует124125[`time.time()`](https://python-all.ru/3.0/library/time.html#time.time)126127(по умолчанию на всех платформах, кроме Windows)128129**-c/*--clock***130131использует132133[`time.clock()`](https://python-all.ru/3.0/library/time.html#time.clock)134135(по умолчанию в Windows)136137**-v/*--verbose***138139выводить необработанные результаты замера; для большей точности (больше знаков) повторите параметр140141**-h/[*--help*](https://python-all.ru/3.0/using/cmdline.html#cmdoption--help)**142143вывести краткое сообщение об использовании и выйти144145Многострочный оператор можно задать, указав каждую строку как отдельный аргумент оператора; строки с отступами возможны, если заключить аргумент в кавычки и использовать начальные пробелы. Несколько параметров [*-s*](https://python-all.ru/3.0/using/cmdline.html#cmdoption-s) обрабатываются аналогично.146147Если *-n* не указано, подходящее количество циклов вычисляется путём перебора последовательных степеней 10, пока общее время не достигнет хотя бы 0,2 секунды.148149Функция таймера по умолчанию зависит от платформы. В Windows [`time.clock()`](https://python-all.ru/3.0/library/time.html#time.clock) имеет микросекундную точность, а [`time.time()`](https://python-all.ru/3.0/library/time.html#time.time) имеет точность 1/60 секунды; в Unix [`time.clock()`](https://python-all.ru/3.0/library/time.html#time.clock) имеет точность 1/100 секунды, а [`time.time()`](https://python-all.ru/3.0/library/time.html#time.time) гораздо более точен. На любой платформе функции таймера по умолчанию измеряют настенное время, а не время CPU. Это означает, что другие процессы, работающие на том же компьютере, могут влиять на измерения. Лучшее, что можно сделать при необходимости точных измерений, – это повторить измерение несколько раз и использовать лучшее время. Опция *-r* хорошо подходит для этого; по умолчанию 3 повторений, вероятно, достаточно в большинстве случаев. В Unix можно использовать [`time.clock()`](https://python-all.ru/3.0/library/time.html#time.clock) для измерения времени CPU.150151> **Примечание**152>153> Существует некоторая базовая накладная нагрузка, связанная с выполнением оператора pass. Приведённый код не пытается её скрыть, но следует знать об этом. Базовую накладную нагрузку можно измерить, вызвав программу без аргументов.154155Базовые накладные расходы различаются между версиями Python! Кроме того, для справедливого сравнения старых версий Python с Python 2.3 может потребоваться использовать опцию [*-O*](https://python-all.ru/3.0/using/cmdline.html#cmdoption-O) Python для старых версий, чтобы избежать измерения инструкций `SET_LINENO`.156157## Примеры158159Вот два примера сеансов (один с использованием командной строки, другой с использованием интерфейса модуля), которые сравнивают стоимость использования [`hasattr()`](https://python-all.ru/3.0/library/functions.html#hasattr) против [`try`](https://python-all.ru/3.0/reference/compound_stmts.html#try)/[`except`](https://python-all.ru/3.0/reference/compound_stmts.html#except) для проверки отсутствующих и существующих атрибутов объектов.160161```python162% timeit.py 'try:' ' str.__bool__' 'except AttributeError:' ' pass'163100000 loops, best of 3: 15.7 usec per loop164% timeit.py 'if hasattr(str, "__bool__"): pass'165100000 loops, best of 3: 4.26 usec per loop166% timeit.py 'try:' ' int.__bool__' 'except AttributeError:' ' pass'1671000000 loops, best of 3: 1.43 usec per loop168% timeit.py 'if hasattr(int, "__bool__"): pass'169100000 loops, best of 3: 2.23 usec per loop170```171172```python173>>> import timeit174>>> s = """\175... try:176... str.__bool__177... except AttributeError:178... pass179... """180>>> t = timeit.Timer(stmt=s)181>>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))18217.09 usec/pass183>>> s = """\184... if hasattr(str, '__bool__'): pass185... """186>>> t = timeit.Timer(stmt=s)187>>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))1884.85 usec/pass189>>> s = """\190... try:191... int.__bool__192... except AttributeError:193... pass194... """195>>> t = timeit.Timer(stmt=s)196>>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))1971.97 usec/pass198>>> s = """\199... if hasattr(int, '__bool__'): pass200... """201>>> t = timeit.Timer(stmt=s)202>>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))2033.15 usec/pass204```205206Чтобы предоставить модулю `timeit` доступ к определённым вами функциям, вы можете передать параметр `setup`, содержащий инструкцию import:207208```python209def test():210 "Stupid test function"211 L = [i for i in range(100)]212213if __name__=='__main__':214 from timeit import Timer215 t = Timer("test()", "from __main__ import test")216 print(t.timeit())217```218