Python에서 함수의 성능을 테스트하기 위해 time() 사용을 즉시 중지합니다.

time.monotonic() 또는 time.perf_counter() 대신 time.time() 함수를 사용하여 Python에서 작업의 성능을 측정하는 데 익숙하고 그 이유가 궁금하다면 이 기사가 적합합니다.

먼저 모듈을 가져옵니다.

improt time

간단한 예부터 시작하겠습니다.

단순화를 위해 작업이 2차원 배열에서 특정 값의 발생 횟수를 세는 것이지만, 이 작업만으로 만족하지 않고 이를 수행하는 데 걸리는 시간도 측정하고 싶다고 가정합니다. 코드 구현은 다음과 같습니다.

def count_value(array, value):
   c = 0
   t_start = time.time()
   for i in array:
       for j in i:
           if j == value:
               c += 1
   t_end = time.time()

   return c, t_end-t_start

이제 일부 배열에서 이 함수를 사용해 보겠습니다.

a_1 = [[1,2],[3,3]]
a_2 = [[33]]
a_3 = [[1 for _ in range(10)] for _ in range(100)]
a_4 = [[i*j for j in range(1000)] for i in range(1000)]

print(count_value(a_1, 3))
print(count_value(a_2, 10))
print(count_value(a_3, 1))
print(count_value(a_4, 44))

산출:

(2, 0.0)
(0, 0.0)
(1000, 0.0)
(6, 0.03124070167541504)

이제 실제 문제를 논의하기 전에 데코레이터를 사용하여 함수의 성능을 측정하는 것을 제안하지만 이 기사의 범위를 벗어나므로 나중에 별도의 기사를 작성할 것입니다. 그럼 위의 문제에 대해 이야기 해 봅시다. 4개의 배열 중 3개에서 검색을 위해 측정된 시간이 0임을 알 수 있습니다. 즉, 검색이 즉각적이라는 의미입니다. 그렇지 않습니다. 여기서 문제는 time.time() 함수가 시스템 시계를 사용한다는 것입니다. 질문:

  • 이 클록의 틱 속도는 충분히 작지 않습니다. 작업이 클록의 두 "틱" 사이에서 실행되면 작업의 실제 길이를 측정할 수 없습니다. 클록의 해상도보다 짧기 때문입니다.

  • 시스템 시계는 업데이트, 시계 보정 또는 윤초와 같은 외부 요인에 의해 수정될 수 있습니다.

이러한 문제를 해결하기 위해 시간 라이브러리에는 monotonic() 및 perf_counter(또는 나노초 대안을 고려하는 경우 4개의 함수: monotonic_ns() 및 perf_counter_ns())의 두 가지 기능이 있습니다.

이러한 함수가 두 가지 문제를 모두 해결한다는 것을 아는 것이 중요합니다. monotonic() 함수는 선형 시계를 기반으로 하며 외부에서 수정할 수 없는 반면 perf_counter() 함수는 더 높은 틱 속도를 갖습니다.

틱 비율 차이 표시

time(), monotonic() 및 perf_counter의 세 함수 모두에 대해 서로 다른 틱 속도를 표시하는 함수를 작성해 보겠습니다. perf_counter_ns()를 사용하여 경과 시간을 측정하겠습니다.

def tick_rate(f):
   tick = 0
   t_start = time.perf_counter_ns()
   last_t = f()
   for i in range(10_000_000):
       t = f()
       if t != last_t:
           tick += 1
       last_t = t
   t_end = time.perf_counter_ns()

   return tick, (t_end-t_start)/(10**9) #divided by 10^9 to convert ns to s

print(tick_rate(time.time))
print(tick_rate(time.monotonic))
print(tick_rate(time.perf_counter))

산출:

(59, 0.9173757)
(50, 0.7825792)
(10000000, 1.615493)

이제 perf_counter() 함수를 사용하여 작은 작업을 측정하는 능력에서 큰 차이를 볼 수 있습니다. 사실 perf_counter()에서 사용하는 클럭의 최대 틱 속도를 측정할 수는 없지만 여전히 큽니다. 기능은 더 긴 작업에 사용할 수 있습니다.

perf_counter()를 사용하는 동일한 예제 이전과 동일한 예제를 사용하되 time() 대신 perf_counter()를 사용합니다.

def count_value(array, value):
   c = 0
   t_start = time.perf_counter()
   for i in array:
       for j in i:
           if j == value:
               c += 1
   t_end = time.perf_counter()

   return c, t_end-t_start

a_1 = [[1,2],[3,3]]
a_2 = [[33]]
a_3 = [[1 for _ in range(10)] for _ in range(100)]
a_4 = [[i*j for j in range(1000)] for i in range(1000)]

print(count_value(a_1, 3))
print(count_value(a_2, 10))
print(count_value(a_3, 1))
print(count_value(a_4, 44))

산출:

(2, 4.7999997150327545e-06)
(0, 1.4000002011016477e-06)
(1000, 7.83999998930085e-05)
(6, 0.036078900000120484)

위에서 본 것처럼 올바른 함수를 사용하여 실제로 소요된 시간을 측정할 수 있습니다.

다음 기사에서는 데코레이터와 함수의 성능을 측정할 때 데코레이터를 사용하는 것이 좋은 이유에 대해 설명하겠습니다. 이 기사를 끝까지 읽으셨다면 제 뉴스레터 구독을 고려해 보십시오. 뉴스레터는 무료이며 계속 동기를 부여해 줍니다!

원문: https://www.raaicode.com/using-time-monotonic-and-perf_counter-to-measure-time-in-python/

추천

출처blog.csdn.net/y1282037271/article/details/129200383