나는 무엇의 개념을 이해 timeit
하지만 내 코드에서 구현하는 방법을 모르겠습니다.
어떻게 두 가지 기능 말을 비교할 수 insertion_sort
와 tim_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 세션에서 사용하려는 경우 두 가지 편리한 옵션이 있습니다.
-
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
-
표준 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)
더 긴 스크립트를 원한다면 timeit
Python 스크립트 내부 로 이동하고 싶을 수도 있습니다 . 명령 줄에서 분석과 타이밍이 더 좋기 때문에 피하는 것이 좋습니다. 대신 쉘 스크립트를 만드는 경향이 있습니다.
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)