#python #python-3.x #performance #time
Вопрос:
Я написал небольшую функцию (timer1) для проверки производительности кода:
def timer1(func,*args): start = time.perf_counter() for i in range(1000): func(*args) return time.perf_counter() - start
Другой вариант этой функции (timer2) выглядит следующим образом:
def timer2(func,*args): for i in range(1000): start = time.perf_counter() func(*args) return time.perf_counter() - start
Печать результата:
timer1_o = timer1(pow,2,1000) timer2_o = timer2(pow,2,1000) print(f"Timer1 function output: {timer1_o}") print(f"Timer2 function output: {timer2_o}") print(f"Difference between timer1 and timer2: {abs(timer1_o - timer2_o)}")
Выход:
Timer1 function output: 0.006264125000000009 Timer2 function output: 6.016999999969297e-06 Difference between timer1 and timer2: 0.00625810800000004
Моя главная проблема заключается в том, почему я получаю разницу во времени выполнения от обеих функций, т. е. timer1 и timer2?
Комментарии:
1. Во втором цикле вы запускаете таймер в цикле, а не раньше . Это означает, что вы засекаете почти ничего не значащее событие.
2.
timer1()
возвращает время, затраченное на 1000 вызовов функций.timer2()
возвращает время, затраченное на один вызов функции (самый последний), так как значениеstart
перезаписывается 999 раз.3. timer1 измеряет 1000 pow(21000), а timer2 измеряет только 1. Поправьте меня, если я ошибаюсь.
4. Но когда я проверил код на «Тонни», я заметил, что во второй функции значение переменной «старт» всегда увеличивается. Если во второй функции значение таймера перезаписывается 999 раз, то почему оно всегда увеличивается?
5. Как он мог что-то сделать, кроме как увеличиться? Оно уменьшилось бы только в том случае, если бы вы двигались назад во времени.
Ответ №1:
Проблема с вашим кодом заключается в timer2
том , как уже упоминалось в комментариях. В python определение переменной в цикле переопределяет переменную каждый раз, когда цикл повторяется, как показано ниже:
for i in range(1000): x = i print(i)
Вывод для приведенного выше кода:
999
Здесь переменная x
присваивается целому i
числу каждый раз, когда цикл повторяется, поэтому сохраняется только последняя итерация. Это ваша ошибка в двух словах: вы пытаетесь получить время начала timer2
и найти время , необходимое для запуска функции ( pow
) 1000 раз. В timer1
, вы определяете запуск только один раз, когда вызывается функция. в timer2
, каждый раз pow
, когда выполняется, start
переопределяется на текущее время.
Вот пример (упрощенный) того, что вы делаете неправильно.
from time import perf_counter, sleep # Correct code start = perf_counter() for i in range(5): print(f"Value of start variable is {start}") # Check the value of start variable sleep(1) # Sleep for 5 * 1 seconds = 5 seconds print(f"Total time taken is {perf_counter() - start}")
Выход:
Value of start variable is 0.036466726 Value of start variable is 0.036466726 Value of start variable is 0.036466726 Value of start variable is 0.036466726 Value of start variable is 0.036466726 Total time taken is 5.00026942
Вы можете ясно видеть, что ценность start
остается прежней
Что ты делаешь в timer2
:
from time import perf_counter, sleep # WRONG code for i in range(5): start = perf_counter() print(f"Value of start variable is {start}") # Check the value of start variable sleep(1) # Sleep for 5 * 1 seconds = 5 seconds print(f"Total time taken is {perf_counter() - start}")
Выход:
Value of start variable is 0.039062328 Value of start variable is 1.038552811 Value of start variable is 2.038591666 Value of start variable is 3.038642618 Value of start variable is 4.038716663 Total time taken is 1.0000285910000004
start
изменяет каждую итерацию вашего timer2
кода.
Ваши timer1
работы просто прекрасны, придерживайтесь их.
Кроме того, пожалуйста, прочитайте/посмотрите о циклах python или поиграйте с ними, пока не узнаете, что они делают. Избегайте задавать вопросы, чтобы вы могли мгновенно найти ответы на них в Google.
Комментарии:
1. Однако моей главной проблемой была работа perf_counter() в целом. Из вашего ответа я понимаю, что perf_counter выглядит следующим образом: в упрощенной версии «Неправильного кода», когда мы повторяем следующий элемент в последовательности и проходим через sleep (), новая переменная start просто (на следующей итерации) добавляет время сна 1 сек к предыдущему сохраненному значению (0,039.. сек, которая была в начале цикла) и начинается с нового сохраненного значения (1 0,039=1,039..сек) в следующем цикле. Этот цикл повторяется до конца. Таким образом, последнее значение «старт» равно 4,03..
2. Но в самом конце (во время печати сообщения) почему perf_counter() принял значение 5 секунд? Почему не последнее сохраненное значение переменной «start»?
3. Это связано с порядком моих утверждений @AnuragGupta — начальная переменная определяется до функции сна, тогда как окончательная
perf_counter
определяется после функции сна. Если вы переместите определениеstart
в послеsleep(1)
, вы получите 0 секунд приблизительно.