Почему я получаю разные выходные данные в этих двух функциях таймера с помощью модуля времени?

#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 секунд приблизительно.