Как измерить время выполнения скрипта Python
Допустим, вы хотите знать время выполнения следующего кода Python:
a = range(100000) b = [] for i in a: b.append(i*2)
Есть несколько способов измерить время, необходимое для выполнения скрипта Python, но вот лучший способ сделать это, и я объясню почему:
import timeit code_to_test = """ a = range(100000) b = [] for i in a: b.append(i*2) """ elapsed_time = timeit.timeit(code_to_test, number=100)/100 print(elapsed_time)
В консоли получим: 0.01137321546
Это вывод, который я получаю на своем Macbook Pro. Итак, это более или менее 1/100 секунды.
Как работает вышеуказанный скрипт
Строка 1: мы импортируем модуль timeit . Строка 3: мы создаем переменную. В этой переменной мы храним код, который хотим протестировать. Этот код должен идти внутри тройных кавычек. Итак, тестовый код предоставляется в виде строки. Строка 10: мы вызываем функцию time.timeit() . Функция timeit() получает тестовый код в качестве аргумента, выполняет его и записывает время выполнения. Чтобы получить точное время, я приказал timeit() выполнить 100 циклов. Поэтому мне пришлось разделить вывод на 100, чтобы получить время выполнения только для одного цикла. Строка 11: мы просто распечатываем время выполнения. Результат — время выполнения в секундах.
Почему timeit() — лучший способ измерить время выполнения кода Python?
1. timeit() автоматически будет использовать time.clock() или time.time() для вас в фоновом режиме, в зависимости от того, какая операционная система вам нужна для получения наиболее точных результатов.
2. timeit() отключает сборщик мусора, который может исказить результаты.
3. timeit() повторяет тест много раз (в нашем случае 100 раз), чтобы минимизировать влияние других задач, выполняемых в вашей операционной системе.
Упражнение:
Кстати, код, который мы тестировали выше, строит список путем умножения элементов другого списка. Я могу достичь того же результата, используя range :
a = range(100000) b = [i*2 for i in a]
Если вам больше нечем заняться и попробуйте выполнить упражнение, попробуйте измерить время выполнения приведенного выше кода с помощью timeit() .
Наконец, совет: закрывайте тяжелые программы, которые запускаются на вашем компьютере, когда вы выполняете такие тесты, чтобы вы получили еще более точные результаты, которые не зависят от тяжелых задач процессора.
Источник:
6 способов измерить скорость программы на Python
Недавно мы решали сложную задачу Эйнштейна с помощью кода на Python, а потом оптимизировали его, чтобы сократить время выполнения. Там всё было просто: с четырёх часов мы оптимизировали время выполнения до долей секунды, и это было явно заметно. Но бывает так, что даже полсекунды оптимизации — это очень хорошо, когда речь идёт о высоконагруженных сервисах. Например, в соцсетях, которыми пользуются сотни тысяч пользователей в минуту. Сегодня мы покажем целых 6 простых способов измерения времени работы кода, которые может использовать каждый.
Как измерять время выполнения кода
В большинстве случаев измерить время работы кода можно так:
- Зафиксировать время начала работы.
- Зафиксировать время окончания работы.
- Вычесть первое значение из второго.
Ещё важно измерять время выполнения кода при одних и тех же условиях:
- конфигурация и мощность компьютера должны совпадать для всех замеров;
- загрузка процессора должна быть одинаковой;
- программа для работы с кодом должна быть одной и той же с одинаковой версией.
Но даже если эти условия выполняются, результаты нескольких замеров могут немного различаться для одного и того же кода. На это могут влиять фоновые процессы, поэтому для точных измерений проводят несколько замеров в чистой среде, когда кроме кода и системных процессов ничего нет.
Если будете заниматься оптимизацией, вот вам на вырост: нужно различать понятия wall time («время на стене») и процессорное время. Первое показывает прошедшее время от начала до конца работы, второе — время, которое процессор затратил на выполнение кода. Их значения могут различаться, если программа ожидает высвобождение ресурсов для выполнения. Но сейчас можно без этих тонкостей.
Модуль datetime
С помощью такого способа можно измерить время выполнения кода в формате часы:минуты:секунды:микросекунды. Мы использовали модуль datetime, когда оптимизировали код для решения загадки Эйнштейна и ускоряли работу программы более чем в 200 тысяч раз.
# подключаем модуль datetime import datetime # фиксируем и выводим время старта работы кода start = datetime.datetime.now() print('Время старта: ' + str(start)) # код, время работы которого измеряем #фиксируем и выводим время окончания работы кода finish = datetime.datetime.now() print('Время окончания: ' + str(finish)) # вычитаем время старта из времени окончания print('Время работы: ' + str(finish - start))
Результат — 51 тысячная секунды. Неплохо, но что покажут другие способы?

Модуль time
Модуль time предоставляет разные возможности для измерения времени работы кода:
- time.time() поможет измерить время работы в секундах. Если нужно получить время в минутах, результат вычисления нужно разделить на 60, в миллисекундах — умножить на 1000.
- time.perf_counter() также можно использовать для измерения времени в секундах, но таймер не будет зависеть от системных часов. Функцию используют, чтобы избежать погрешностей. Функция time.perf_counter_ns() вернёт значение в наносекундах.
- time.monotonic() подходит для больших программ, поскольку эта функция не зависит от корректировки времени системы. Функция использует отдельный таймер, как и time.perf_counter(), но имеет более низкое разрешение. С помощью time.monotonic_ns() можно получить результат в наносекундах.
- time.process_time() поможет получить сумму системного и пользовательского процессорного времени в секундах, не включая время сна. Если процесс выполнения блокируется функцией time.sleep() или приостанавливается операционной системой, это время не включается в отчётное. Для наносекунд есть функция time.process_time_ns(), но её поддерживают не все платформы.
- time.thread_time() сообщит время выполнения текущего потока, а не процесса. Если в коде есть функция time.sleep(), время её выполнения не будет включено.
Time.time(). Давайте посчитаем время выполнения нашего кода с помощью функции time.time() в миллисекундах:
# подключаем модуль time import time # фиксируем время старта работы кода start = time.time() # код, время работы которого измеряем #фиксируем время окончания работы кода finish = time.time() # вычитаем время старта из времени окончания и получаем результат в миллисекундах res = finish - start res_msec = res * 1000 print('Время работы в миллисекундах: ', res_msec)
Получаем результат: 61 тысячная секунды. Результат отличается от предыдущего, тут уже нужно было бы хорошо сделать серию тестов и посчитать среднее значение.

Time.perf_counter(). Посчитаем время выполнения нашего кода с помощью функции time.perf_counter() в секундах:
# подключаем модуль time import time # фиксируем время старта работы кода start = time.perf_counter() # код, время работы которого измеряем #фиксируем время окончания работы кода finish = time.perf_counter() # вычитаем время старта из времени окончания и выводим результат print('Время работы: ' + str(finish - start))
Мы получили 51 тысячную секунды — почти такой же результат, как и в самый первый раз. Кажется, что это точное время, но посмотрим, что будет дальше.

Time.monotonic_ns(). Посчитаем время выполнения нашего кода с помощью функции time.monotonic_ns() в наносекундах:
# подключаем модуль time import time # фиксируем время старта работы кода start = time.monotonic_ns() # код, время работы которого измеряем #фиксируем время окончания работы кода finish = time.monotonic_ns() # вычитаем время старта из времени окончания и получаем результат в наносекундах print('Время работы в наносекундах: ' + str(finish - start))
Результат примерно такой же — 52 тысячные секунды, но количество цифр в результате меньше, чем в предыдущем случае.

Time.process_time(). Посчитаем сумму системного и пользовательского процессорного времени в секундах:
# подключаем модуль time import time # фиксируем время старта работы кода start = time.process_time() # код, время работы которого измеряем #фиксируем время окончания работы кода finish = time.process_time() # вычитаем время старта из времени окончания и выводим результат print('Время работы: ' + str(finish - start))
Время работы снова выросло — с 51 до 62 тысячных секунды. Для одних программ такой разброс вообще некритичен, а для других это может означать, что нужно провести больше тестов.

Time.thread_time(). Наконец, посчитаем время выполнения кода с помощью time.thread_time():
# подключаем модуль time import time # фиксируем время старта работы кода start = time.thread_time() # код, время работы которого измеряем #фиксируем время окончания работы кода finish = time.thread_time() # вычитаем время старта из времени окончания и выводим результат print('Время работы: ' + str(finish - start))
Время работы снова выглядит правдоподобно в сравнении с предыдущим результатом.

Что дальше
В следующий раз продолжим оптимизировать наш код решения задачи Эйнштейна: отформатируем и избавимся от вложенных данных. Подпишитесь, чтобы не пропустить продолжение.
Python как измерить время выполнения кода
На этом шаге мы рассмотрим использование модуля timeit .
Модуль timeit позволяет измерить время выполнения небольших фрагментов кода с целью оптимизации программы. Прежде чем использовать модуль, необходимо подключить его с помощью инструкции:
from timeit import Timer
Измерения производятся с помощью класса Timer . Конструктор класса имеет следующий формат:
Timer([stmt='pass'][, setup='pass'][, timer=])
В параметре stmt указывается код (в виде строки), время выполнения которого предполагается измерить. Параметр setup позволяет указать код, который будет выполнен перед измерением времени выполнения кода в параметре stmt . Например, в параметре setup можно подключить модуль.
Получить время выполнения можно с помощью метода timeit ([number=1000000]) . В параметре number указывается количество повторений. Для примера просуммируем числа от 1 до 10000 тремя способами и выведем время выполнения каждого способа.
#-*- coding: utf-8 -*- from timeit import Timer code1 = """\ i, j = 1, 0 while i < 10001: j += i i += 1 """t1 = Timer(stmt=code1) print("while:", t1.timeit(number=10000)) code2 = """\ j = 0 for i in range(1, 10001): j += i """ t2 = Timer(stmt=code2) print("for:", t2.timeit(number=10000)) code3 = """\ j = sum (range(1, 10001)) """ t3 = Timer(stmt=code3) print("sum:", t3.timeit(number=10000)) input ()
Архив с файлом можно взять здесь.
Примерный результат выполнения (зависит от мощности компьютера):
while: 25.13958657675797 for: 14.858756346126274 sum: 5.050326964385583
Как видно из результата, цикл for работает почти в два раза быстрее цикла while , а функция sum () в данном случае является самым оптимальным решением задачи.
Метод repeat ([repeat=3] [, number=1000000]) вызывает метод timeit () указанное количество раз (задается в параметре repeat ) и возвращает список значений. Аргумент number передается в качестве параметра методу timeit () . Для примера создадим список со строковыми представлениями чисел от 1 до 10000. В первом случае для создания списка используем цикл for и метод append () , а во втором — генератор списков.
# -*- coding: utf-8 -*- from timeit import Timer code1 = """\ arr1 = [] for i in range(1, 10001): arr1.append(str(i)) """ t1 = Timer(stmt=code1) print("append:", t1.repeat(repeat=3, number=2000)) code2 = """\ arr2 = [str(i) for i >in range(1, 10001)] """ t2 = Timer(stmt=code2) print("генератор:", t2.repeat(repeat=3, number=2000)) input()
Архив с файлом можно взять здесь.
Примерный результат выполнения:
append: [12.780722522318046, 12.724886804338505, 12.903999274243034] генератор: [10.290514465192551, 10.268080216531082, 10.219959743593058]
Как видно из результата, генераторы списков работают быстрее.
Со следующего шага мы начнем рассматривать пользовательские функции .
Измерение времени выполнения скрипта#
Для оценки времени выполнения скрипта есть несколько вариантов. Тут используются самые простые варианты:
- утилита Linux time
- и модуль Python datetime
При оценке времени выполнения скрипта в данном случае не важна высокая точность. Главное — сравнить время выполнения скрипта в разных вариантах.
time #
Утилита time в Linux позволяет замерить время выполнения скрипта. Для использования утилиты time достаточно написать time перед строкой запуска скрипта:
$ time python thread_paramiko.py . real 0m4.712s user 0m0.336s sys 0m0.064s
Нас интересует real время. В данном случае это 4.7 секунд.
datetime #
Второй вариант — модуль datetime. Этот модуль позволяет работать со временем и датами в Python.
from datetime import datetime import time start_time = datetime.now() #Тут выполняются действия time.sleep(5) print(datetime.now() - start_time)
$ python test.py 0:00:05.004949