[python] timeit 모듈 사용법

나는 무엇의 개념을 이해 timeit하지만 내 코드에서 구현하는 방법을 모르겠습니다.

어떻게 두 가지 기능 말을 비교할 수 insertion_sorttim_sort함께 timeit?



답변

timeit이 작동 하는 방법 은 설정 코드를 한 번 실행 한 다음 일련의 명령문을 반복해서 호출하는 것입니다. 따라서 정렬을 테스트하려는 경우 전체 정렬에서 한 번의 패스가 이미 정렬 된 데이터가있는 다음 패스에 영향을 미치지 않도록주의해야합니다 (물론 Timsort가 최상의 성능을 발휘하기 때문에 실제로 빛나게합니다) 데이터가 이미 부분적으로 주문 된 경우).

정렬 테스트를 설정하는 방법의 예는 다음과 같습니다.

>>> import timeit

>>> setup = '''
import random

random.seed('slartibartfast')
s = [random.random() for i in range(1000)]
timsort = list.sort
'''

>>> print min(timeit.Timer('a=s[:]; timsort(a)', setup=setup).repeat(7, 1000))
0.334147930145

일련의 명령문은 모든 패스에서 정렬되지 않은 데이터의 새로운 사본을 만듭니다.

또한 측정 제품군을 7 회 실행하고 최상의 시간 만 유지하는 타이밍 기술에 유의하십시오. 이는 시스템에서 실행중인 다른 프로세스로 인한 측정 왜곡을 줄이는 데 실제로 도움이됩니다.

이것들은 timeit을 올바르게 사용하는 팁입니다. 도움이 되었기를 바랍니다 🙂


답변

timeit대화식 Python 세션에서 사용하려는 경우 두 가지 편리한 옵션이 있습니다.

  1. IPython 쉘을 사용하십시오 . 편리한 %timeit특수 기능이 있습니다.

    In [1]: def f(x):
       ...:     return x*x
       ...:
    
    In [2]: %timeit for x in range(100): f(x)
    100000 loops, best of 3: 20.3 us per loop
  2. 표준 Python 인터프리터에서는 대화식 세션 중에 이전에 정의한 함수 및 기타 이름을 __main__setup 문에서 가져 와서 액세스 할 수 있습니다 .

    >>> def f(x):
    ...     return x * x
    ...
    >>> import timeit
    >>> timeit.repeat("for x in range(100): f(x)", "from __main__ import f",
                      number=100000)
    [2.0640320777893066, 2.0876040458679199, 2.0520210266113281]

답변

비밀로 알려 드리겠습니다. 사용하는 가장 좋은 방법 timeit은 명령 줄에 있습니다.

명령 행에서 timeit적절한 통계 분석을 수행합니다. 가장 짧은 실행 시간을 알려줍니다. 이것은 모두 좋기 때문에 좋습니다타이밍의 오류가 양수 . 따라서 가장 짧은 시간은 오류가 가장 적습니다. 컴퓨터가 계산할 수있는 것보다 빠르게 계산할 수 없기 때문에 부정적인 오류를 얻을 수있는 방법이 없습니다!

따라서 명령 행 인터페이스는 다음과 같습니다.

%~> python -m timeit "1 + 2"
10000000 loops, best of 3: 0.0468 usec per loop

아주 간단합니다.

당신은 물건을 설정할 수 있습니다 :

%~> python -m timeit -s "x = range(10000)" "sum(x)"
1000 loops, best of 3: 543 usec per loop

유용합니다!

여러 줄을 원한다면 쉘의 자동 연속을 사용하거나 별도의 인수를 사용할 수 있습니다.

%~> python -m timeit -s "x = range(10000)" -s "y = range(100)" "sum(x)" "min(y)"
1000 loops, best of 3: 554 usec per loop

그것은 설정을 제공합니다

x = range(1000)
y = range(100)

그리고 시간

sum(x)
min(y)

더 긴 스크립트를 원한다면 timeitPython 스크립트 내부 로 이동하고 싶을 수도 있습니다 . 명령 줄에서 분석과 타이밍이 더 좋기 때문에 피하는 것이 좋습니다. 대신 쉘 스크립트를 만드는 경향이 있습니다.

 SETUP="

 ... # lots of stuff

 "

 echo Minmod arr1
 python -m timeit -s "$SETUP" "Minmod(arr1)"

 echo pure_minmod arr1
 python -m timeit -s "$SETUP" "pure_minmod(arr1)"

 echo better_minmod arr1
 python -m timeit -s "$SETUP" "better_minmod(arr1)"

 ... etc

여러 초기화로 인해 시간이 조금 더 걸릴 수 있지만 일반적으로 큰 문제는 아닙니다.


하지만 사용 하고 싶다면timeit 모듈 내부에?

간단한 방법은 다음과 같습니다.

def function(...):
    ...

timeit.Timer(function).timeit(number=NUMBER)

그 누적 당신 (제공 하지 그 횟수만큼 실행하는 최소한이 !) 시간을줍니다.

좋은 분석을 얻으려면 .repeat최소 사용 하고 사용하십시오.

min(timeit.Timer(function).repeat(repeat=REPEATS, number=NUMBER))

일반적으로 오버 헤드를 낮추는 functools.partial대신 이것을 결합해야합니다 lambda: .... 따라서 다음과 같은 것을 가질 수 있습니다.

from functools import partial

def to_time(items):
    ...

test_items = [1, 2, 3] * 100
times = timeit.Timer(partial(to_time, test_items)).repeat(3, 1000)

# Divide by the number of repeats
time_taken = min(times) / 1000

당신은 또한 할 수 있습니다 :

timeit.timeit("...", setup="from __main__ import ...", number=NUMBER)

명령 줄에서 인터페이스에 더 가까운 것을 제공 하지만 훨씬 덜 멋진 방식으로 제공합니다. 은 "from __main__ import ..."당신이 만든 인공 환경 내부에 메인 모듈의 코드를 사용할 수 있습니다 timeit.

이것은 편리한 래퍼 Timer(...).timeit(...)이므로 타이밍에 특히 좋지 않습니다. 나는 Timer(...).repeat(...)위에서 보여준 것처럼 개인적으로 사용하는 것을 훨씬 선호합니다 .


경고

timeit사방에 몇 가지 경고가 있습니다.

  • 오버 헤드는 계산되지 않습니다. x += 1추가 시간이 얼마나 걸리는지 알아 보려면 시간을 정하고 싶다고 가정 해보십시오 .

    >>> python -m timeit -s "x = 0" "x += 1"
    10000000 loops, best of 3: 0.0476 usec per loop

    글쎄, 그것은 0.0476 µs 가 아닙니다 . 당신은 그것 보다 적은 것을 알고 있습니다. 모든 오류는 양수입니다.

    따라서 순수한 오버 헤드를 시도하고 찾으십시오 .

    >>> python -m timeit -s "x = 0" ""
    100000000 loops, best of 3: 0.014 usec per loop

    타이밍만으로도 30 % 의 우수한 오버 헤드입니다! 이로 인해 상대 타이밍이 크게 왜곡 될 수 있습니다. 그러나 당신은 정말로 타이밍을 추가하는 것에 관심을 가졌습니다. 조회 시간 x도 오버 헤드에 포함되어야합니다.

    >>> python -m timeit -s "x = 0" "x"
    100000000 loops, best of 3: 0.0166 usec per loop

    그 차이는 그다지 크지 않지만 거기에 있습니다.

  • 돌연변이 방법은 위험합니다.

    >>> python -m timeit -s "x = [0]*100000" "while x: x.pop()"
    10000000 loops, best of 3: 0.0436 usec per loop

    그러나 그것은 완전히 잘못입니다! x첫 번째 반복 후 빈 목록입니다. 다시 초기화해야합니다.

    >>> python -m timeit "x = [0]*100000" "while x: x.pop()"
    100 loops, best of 3: 9.79 msec per loop

    그러나 오버 헤드가 많이 있습니다. 별도로 설명하십시오.

    >>> python -m timeit "x = [0]*100000"
    1000 loops, best of 3: 261 usec per loop

    여기서 오버 헤드를 빼는 것은 오버 헤드가 시간의 작은 부분 이기 때문에 합리적 입니다.

    예를 들어 삽입 정렬과 팀 정렬 모두 이미 정렬 된 목록에 대해 완전히 특이한 타이밍 동작을 가지고 있음을 주목할 가치가 있습니다. 즉 random.shuffle, 타이밍을 방해하지 않으려면 여러 종류 가 필요합니다 .


답변

두 블록의 코드 / 함수를 빠르게 비교하려면 다음을 수행하십시오.

import timeit

start_time = timeit.default_timer()
func1()
print(timeit.default_timer() - start_time)

start_time = timeit.default_timer()
func2()
print(timeit.default_timer() - start_time)


답변

timeit을 사용하는 가장 쉬운 방법은 명령 줄에서 찾는 것입니다.

주어진 test.py :

def InsertionSort(): ...
def TimSort(): ...

다음과 같이 timeit을 실행하십시오.

% python -mtimeit -s'import test' 'test.InsertionSort()'
% python -mtimeit -s'import test' 'test.TimSort()'


답변

나를 위해, 이것은 가장 빠른 방법입니다.

import timeit
def foo():
    print("here is my code to time...")


timeit.timeit(stmt=foo, number=1234567)


답변

# Генерация целых чисел

def gen_prime(x):
    multiples = []
    results = []
    for i in range(2, x+1):
        if i not in multiples:
            results.append(i)
            for j in range(i*i, x+1, i):
                multiples.append(j)

    return results


import timeit

# Засекаем время

start_time = timeit.default_timer()
gen_prime(3000)
print(timeit.default_timer() - start_time)

# start_time = timeit.default_timer()
# gen_prime(1001)
# print(timeit.default_timer() - start_time)