etc./StackOverFlow

Python에서 경과 시간을 측정하는 방법은 무엇입니까?

청렴결백한 만능 재주꾼 2022. 1. 14. 12:32
반응형

질문자 :gilbert8


내가 원하는 것은 내 코드의 어딘가에서 시간 계산을 시작한 다음 몇 가지 기능을 실행하는 데 걸린 시간을 측정하기 위해 전달된 시간을 얻는 것입니다. 나는 timeit 모듈을 잘못 사용하고 있다고 생각하지만 문서는 나에게 혼란 스럽습니다.

 import timeit start = timeit.timeit() print("hello") end = timeit.timeit() print(end - start)


두 지점 사이의 경과된 벽시계 시간을 측정하려는 경우 time.time() 사용할 수 있습니다.

 import time start = time.time() print("hello") end = time.time() print(end - start)

이것은 실행 시간을 초 단위로 제공합니다.

3.3 이후의 또 다른 옵션은 요구 사항에 따라 perf_counter 또는 process_time time.clock 을 사용하는 것이 권장되었습니다 (Amber에게 감사드립니다). 그러나 현재 사용되지 않습니다.

Unix에서는 현재 프로세서 시간을 초 단위의 부동 소수점 숫자로 반환합니다. 정밀도, 그리고 사실 "프로세서 시간"의 의미에 대한 바로 그 정의는 같은 이름의 C 함수에 따라 달라집니다.

QueryPerformanceCounter() 기반으로 이 함수에 대한 첫 번째 호출 이후 경과된 벽시계 초를 부동 소수점 숫자로 반환합니다. 해상도는 일반적으로 1마이크로초보다 좋습니다.

버전 3.3부터 폐지: 이 함수의 동작은 플랫폼에 따라 다릅니다. 잘 정의된 동작을 가지려면 요구 사항에 따라 대신 perf_counter() 또는 process_time()


NPE

사용 timeit.default_timer 대신 timeit.timeit . 전자는 플랫폼 및 Python 버전에서 사용 가능한 최고의 시계를 자동으로 제공합니다.

 from timeit import default_timer as timer start = timer() # ... end = timer() print(end - start) # Time in seconds, eg 5.38091952400282

timeit.default_timer 는 OS에 따라 time.time() 또는 time.clock()에 할당됩니다. Python 3.3 이상에서 default_timer 는 모든 플랫폼에서 time.perf_counter()입니다. Python - time.clock() 대 time.time() - 정확도를 참조하십시오.

또한보십시오:


jfs

Python 3만 해당:

() time.clock 때문에 파이썬 3.3으로 사용되지 않습니다 , 당신은 사용하기를 원할 것입니다 time.perf_counter() 시스템 전체의 타이밍, 또는에 대한 time.process_time() 과정 전체 타이밍, 당신이 사용하는 데 사용 다만 방법 time.clock() :

 import time t = time.process_time() #do some stuff elapsed_time = time.process_time() - t

새로운 기능인 process_time 에는 절전 중에 경과된 시간이 포함되지 않습니다.


Pierre Prinetti

초 단위 측정 시간:

 from timeit import default_timer as timer from datetime import timedelta start = timer() end = timer() print(timedelta(seconds=end-start))

출력 :

 0:00:01.946339

Gal Bracha

시간을 지정하려는 기능이 주어지면

test.py:

 def foo(): # print "hello" return "hello"

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

 % python -mtimeit -s'import test' 'test.foo()' 1000000 loops, best of 3: 0.254 usec per loop

함수의 속도를 비교하기 위해 (순진하게) time.time 또는 time.clock 을 사용하지 마십시오. 그들은 잘못된 결과를 줄 수 있습니다 .

추신. 시간을 측정하려는 함수에 print 문을 넣지 마십시오. 그렇지 않으면 측정된 시간 은 터미널 의 속도에 따라 달라집니다.


unutbu

with 블록에 들어갈 때 시작 시간을 자동으로 기억한 다음 블록 종료 시 종료 시간을 고정하는 컨텍스트 관리자로 이 작업을 수행하는 것은 재미있습니다. 약간의 속임수를 사용하면 동일한 컨텍스트 관리자 함수에서 블록 내부의 실행 경과 시간 집계를 얻을 수도 있습니다.

핵심 라이브러리에는 이것이 없습니다(그러나 아마도 있어야 합니다). 일단 배치되면 다음과 같은 작업을 수행할 수 있습니다.

 with elapsed_timer() as elapsed: # some lengthy code print( "midpoint at %.2f seconds" % elapsed() ) # time so far # other lengthy code print( "all done at %.2f seconds" % elapsed() )

트릭을 수행하기에 충분한 컨텍스트 관리자 코드는 다음과 같습니다.

 from contextlib import contextmanager from timeit import default_timer @contextmanager def elapsed_timer(): start = default_timer() elapser = lambda: default_timer() - start yield lambda: elapser() end = default_timer() elapser = lambda: end-start

그리고 실행 가능한 데모 코드:

 import time with elapsed_timer() as elapsed: time.sleep(1) print(elapsed()) time.sleep(2) print(elapsed()) time.sleep(3)

이 함수의 설계에 따라 elapsed() 의 반환 값은 블록 종료 시 고정되고 추가 호출은 동일한 기간(이 장난감 예제에서는 약 6초)을 반환합니다.


gojomo

나는 이것을 선호한다. timeit 문서는 너무 혼란스럽습니다.

 from datetime import datetime start_time = datetime.now() # INSERT YOUR CODE time_elapsed = datetime.now() - start_time print('Time elapsed (hh:mm:ss.ms) {}'.format(time_elapsed))

여기에는 서식이 적용되지 않습니다. time_elapsed를 해석할 수 있도록 출력물에 hh:mm:ss time_elapsed


user1761806

이 작업을 수행하는 또 다른 방법은 다음과 같습니다.

 >> from pytictoc import TicToc >> t = TicToc() # create TicToc instance >> t.tic() # Start timer >> # do something >> t.toc() # Print elapsed time Elapsed time is 2.612231 seconds.

전통적인 방법과 비교:

 >> from time import time >> t1 = time() >> # do something >> t2 = time() >> elapsed = t2 - t1 >> print('Elapsed time is %f seconds.' % elapsed) Elapsed time is 2.612231 seconds.

설치:

 pip install pytictoc

자세한 내용은 PyPi 페이지 를 참조하세요.


Mingwei He

여기에 몇 가지 다른 기사뿐만 아니라 많은 좋은 답변을 거친 후 내 발견이 있습니다.

timeittime.time 사이에서 토론하는 경우 timeit 에는 두 가지 이점이 있습니다.

  1. timeit 은 OS 및 Python 버전에서 사용할 수 있는 최상의 타이머를 선택합니다.
  2. timeit 가비지 수집을 비활성화하지만, 이것은 당신이 원할 수도 있고 원하지 않을 수도 있습니다.

이제 문제는 설정이 필요하고 가져오기가 많을 때 상황이 추악해지기 때문에 timeit 이상적으로는 데코레이터를 원하거나 블록 및 측정 시간과 with 불행히도 여기에 사용할 수 있는 기본 제공 기능이 없으므로 두 가지 옵션이 있습니다.

옵션 1: 시간예산 라이브러리 사용

timebudget 은 pip 설치 후 한 줄의 코드에서 사용할 수 있는 다용도의 매우 간단한 라이브러리입니다.

 @timebudget # Record how long this function takes def my_method(): # my code

옵션 2: 내 작은 모듈 사용

나는 timing.py 라는 작은 타이밍 유틸리티 모듈을 아래에 만들었습니다. 이 파일을 프로젝트에 드롭하고 사용을 시작하십시오. 유일한 외부 종속성은 다시 작은 runstats입니다.

이제 함수 앞에 데코레이터를 배치하여 모든 함수의 시간을 측정할 수 있습니다.

 import timing @timing.MeasureTime def MyBigFunc(): #do something time consuming for i in range(10000): print(i) timing.print_all_timings()

코드의 일부에 시간 with 블록을 사용하여 내부에 넣으십시오.

 import timing #somewhere in my code with timing.MeasureBlockTime("MyBlock"): #do something time consuming for i in range(10000): print(i) # rest of my code timing.print_all_timings()

장점:

여러 반 지원 버전이 떠돌아다니고 있으므로 몇 가지 주요 사항을 지적하고자 합니다.

  1. 앞에서 설명한 이유로 time.time 대신 timeit의 timer를 사용합니다.
  2. 원하는 경우 타이밍 중에 GC를 비활성화할 수 있습니다.
  3. 데코레이터는 명명되거나 명명되지 않은 매개변수가 있는 함수를 허용합니다.
  4. 블록 타이밍에서 인쇄를 비활성화하는 기능( with timing.MeasureBlockTime() as tt.elapsed 다음 t.elapsed와 함께 사용).
  5. 블록 타이밍에 대해 gc를 활성화 상태로 유지하는 기능.

Shital Shah

작업 기간을 계산하는 가장 쉬운 방법:

 import time start_time = time.monotonic() <operations, programs> print('seconds: ', time.monotonic() - start_time)

공식 문서는 여기 .


Wojciech Moszczyński

time.time 을 사용하여 실행을 측정하면 컴퓨터의 다른 프로세스에서 소비한 실행 시간을 포함하여 명령의 전체 실행 시간을 알 수 있습니다. 사용자가 눈치채는 시점이지만 다른 코드 조각/알고리즘/함수/...

timeit 대한 추가 정보:

프로파일링에 대한 더 깊은 통찰력을 원하는 경우:

업데이트 : 작년에 http://pythonhosted.org/line_profiler/ 를 많이 사용했는데 매우 유용하고 Pythons 프로필 모듈 대신 사용하는 것이 좋습니다.


rocksportrocker

python cProfile 및 pstats 모듈은 기존 기능 주위에 코드를 추가하지 않고도 특정 기능에서 경과된 시간을 측정하기 위한 뛰어난 지원을 제공합니다.

예를 들어 python 스크립트 timeFunctions.py가 있는 경우:

 import time def hello(): print "Hello :)" time.sleep(0.1) def thankyou(): print "Thank you!" time.sleep(0.05) for idx in range(10): hello() for idx in range(100): thankyou()

프로파일러를 실행하고 파일에 대한 통계를 생성하려면 다음을 실행하면 됩니다.

 python -m cProfile -o timeStats.profile timeFunctions.py

이것이 하는 일은 cProfile 모듈을 사용하여 timeFunctions.py의 모든 기능을 프로파일링하고 timeStats.profile 파일에서 통계를 수집하는 것입니다. 기존 모듈(timeFunctions.py)에 코드를 추가할 필요가 없었으며 이는 모든 모듈에서 수행할 수 있습니다.

통계 파일이 있으면 다음과 같이 pstats 모듈을 실행할 수 있습니다.

 python -m pstats timeStats.profile

이것은 당신에게 좋은 기능을 많이 제공하는 대화형 통계 브라우저를 실행합니다. 특정 사용 사례의 경우 기능에 대한 통계를 확인할 수 있습니다. 두 기능에 대한 통계를 확인하는 예제에서 다음을 보여줍니다.

 Welcome to the profile statistics browser. timeStats.profile% stats hello <timestamp> timeStats.profile 224 function calls in 6.014 seconds Random listing order was used List reduced from 6 to 1 due to restriction <'hello'> ncalls tottime percall cumtime percall filename:lineno(function) 10 0.000 0.000 1.001 0.100 timeFunctions.py:3(hello) timeStats.profile% stats thankyou <timestamp> timeStats.profile 224 function calls in 6.014 seconds Random listing order was used List reduced from 6 to 1 due to restriction <'thankyou'> ncalls tottime percall cumtime percall filename:lineno(function) 100 0.002 0.000 5.012 0.050 timeFunctions.py:7(thankyou)

더미 예제는 많은 작업을 수행하지 않지만 수행할 수 있는 작업에 대한 아이디어를 제공합니다. 이 접근 방식의 가장 좋은 점은 이러한 숫자를 얻고 분명히 프로파일링에 도움이 되도록 기존 코드를 편집할 필요가 없다는 것입니다.


sanchitarora

다음은 타이밍 코드에 대한 또 다른 컨텍스트 관리자입니다.

용법:

 from benchmark import benchmark with benchmark("Test 1+1"): 1+1 => Test 1+1 : 1.41e-06 seconds

또는 시간 값이 필요한 경우

 with benchmark("Test 1+1") as b: 1+1 print(b.time) => Test 1+1 : 7.05e-07 seconds 7.05233786763e-07

벤치마크.py :

 from timeit import default_timer as timer class benchmark(object): def __init__(self, msg, fmt="%0.3g"): self.msg = msg self.fmt = fmt def __enter__(self): self.start = timer() return self def __exit__(self, *args): t = timer() - self.start print(("%s : " + self.fmt + " seconds") % (self.msg, t)) self.time = t

http://dabeaz.blogspot.fr/2010/02/context-manager-for-timing-benchmarks.html 에서 수정


Brian Burns

다음은 "hh:mm:ss" 문자열을 반환하는 작은 타이머 클래스입니다.

 class Timer: def __init__(self): self.start = time.time() def restart(self): self.start = time.time() def get_time_hhmmss(self): end = time.time() m, s = divmod(end - self.start, 60) h, m = divmod(m, 60) time_str = "%02d:%02d:%02d" % (h, m, s) return time_str

용법:

 # Start timer my_timer = Timer() # ... do something # Get time string: time_hhmmss = my_timer.get_time_hhmmss() print("Time elapsed: %s" % time_hhmmss ) # ... use the timer again my_timer.restart() # ... do something # Get time: time_hhmmss = my_timer.get_time_hhmmss() # ... etc

Danijel

프로파일러 모듈을 사용합니다. 그것은 매우 상세한 프로필을 제공합니다.

 import profile profile.run('main()')

다음과 같이 출력합니다.

 5 function calls in 0.047 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.000 0.000 :0(exec) 1 0.047 0.047 0.047 0.047 :0(setprofile) 1 0.000 0.000 0.000 0.000 <string>:1(<module>) 0 0.000 0.000 profile:0(profiler) 1 0.000 0.000 0.047 0.047 profile:0(main()) 1 0.000 0.000 0.000 0.000 two_sum.py:2(twoSum)

매우 유익한 정보를 찾았습니다.


Leonid Ganeline

나는 간단한 것을 좋아한다(python 3):

 from timeit import timeit timeit(lambda: print("hello"))

출력은 단일 실행의 경우 마이크로초입니다.

 2.430883963010274

설명 : timeit은 기본적으로 익명 함수를 100만 번 실행하며 결과는 초 단위 로 제공됩니다. 따라서 1회의 단일 실행에 대한 결과는 동일한 양이지만 평균적으로 마이크로초 단위 입니다.


느린 작업의 경우 더 적은 의 반복을 추가하거나 영원히 기다릴 수 있습니다.

 import time timeit(lambda: time.sleep(1.5), number=1)

총 반복 횟수 에 대한 출력은 항상 초 단위입니다.

 1.5015795179999714

David

(Ipython만 해당) %timeit 를 사용하여 평균 처리 시간을 측정할 수 있습니다.

 def foo(): print "hello"

그리고:

 %timeit foo()

결과는 다음과 같습니다.

 10000 loops, best of 3: 27 µs per loop

Eyal Ch

python3에서:

 from time import sleep, perf_counter as pc t0 = pc() sleep(1) print(pc()-t0)

우아하고 짧습니다.


DmitrySemenov

timeit 를 사용하는 또 다른 방법은 다음과 같습니다.

 from timeit import timeit def func(): return 1 + 1 time = timeit(func, number=1) print(time)

raacer

재귀적으로 모든 함수 호출에 대한 통찰력을 얻으려면 다음을 수행하십시오.

 %load_ext snakeviz %%snakeviz

Jupyter 노트북 에서 두 줄의 코드 만 사용하면 멋진 대화형 다이어그램이 생성됩니다. 예를 들어:

여기에 이미지 설명 입력

다음은 코드입니다. % 로 시작하는 두 줄은 snakeviz를 사용하는 데 필요한 유일한 추가 코드 줄입니다.

 # !pip install snakeviz %load_ext snakeviz import glob import hashlib %%snakeviz files = glob.glob('*.txt') def print_files_hashed(files): for file in files: with open(file) as f: print(hashlib.md5(f.read().encode('utf-8')).hexdigest()) print_files_hashed(files)

노트북 외부에서 snakeviz를 실행하는 것도 가능할 것 같습니다. 스네이크비즈 웹사이트 에서 더 많은 정보를 얻을 수 있습니다.


Guillaume Chevalier

일종의 슈퍼 나중 응답이지만 누군가에게는 목적이 될 수 있습니다. 이것은 내가 생각하기에 매우 깨끗한 방법입니다.

 import time def timed(fun, *args): s = time.time() r = fun(*args) print('{} execution took {} seconds.'.format(fun.__name__, time.time()-s)) return(r) timed(print, "Hello")

"print"는 Python 2.7이 아니라 Python 3의 함수입니다. 그러나 다른 기능과 함께 작동합니다. 건배!


Andreas Herman

다음은 내가 일반 유틸리티로 사용하는 꽤 잘 문서화되고 완전한 유형 힌트 데코레이터입니다.

 from functools import wraps from time import perf_counter from typing import Any, Callable, Optional, TypeVar, cast F = TypeVar("F", bound=Callable[..., Any]) def timer(prefix: Optional[str] = None, precision: int = 6) -> Callable[[F], F]: """Use as a decorator to time the execution of any function. Args: prefix: String to print before the time taken. Default is the name of the function. precision: How many decimals to include in the seconds value. Examples: >>> @timer() ... def foo(x): ... return x >>> foo(123) foo: 0.000...s 123 >>> @timer("Time taken: ", 2) ... def foo(x): ... return x >>> foo(123) Time taken: 0.00s 123 """ def decorator(func: F) -> F: @wraps(func) def wrapper(*args: Any, **kwargs: Any) -> Any: nonlocal prefix prefix = prefix if prefix is not None else f"{func.__name__}: " start = perf_counter() result = func(*args, **kwargs) end = perf_counter() print(f"{prefix}{end - start:.{precision}f}s") return result return cast(F, wrapper) return decorator

사용 예:

 from timer import timer @timer(precision=9) def takes_long(x: int) -> bool: return x in (i for i in range(x + 1)) result = takes_long(10**8) print(result)

산출:

 takes_long: 4.942629056s True

doctest는 다음을 통해 확인할 수 있습니다.

 $ python3 -m doctest --verbose -o=ELLIPSIS timer.py

그리고 유형 힌트:

 $ mypy timer.py

ruohola

timeit을 사용할 수 있습니다.

다음은 Python REPL을 사용하여 매개변수를 사용하는 naive_func를 테스트하는 방법에 대한 예입니다.

 >>> import timeit >>> def naive_func(x): ... a = 0 ... for i in range(a): ... a += i ... return a >>> def wrapper(func, *args, **kwargs): ... def wrapper(): ... return func(*args, **kwargs) ... return wrapper >>> wrapped = wrapper(naive_func, 1_000) >>> timeit.timeit(wrapped, number=1_000_000) 0.4458435332577161

함수에 매개변수가 없으면 래퍼 함수가 필요하지 않습니다.


Vlad Bezden

시간을 사람이 읽을 수 있는 시간으로 변환할 수도 있습니다.

 import time, datetime start = time.clock() def num_multi1(max): result = 0 for num in range(0, 1000): if (num % 3 == 0 or num % 5 == 0): result += num print "Sum is %d " % result num_multi1(1000) end = time.clock() value = end - start timestamp = datetime.datetime.fromtimestamp(value) print timestamp.strftime('%Y-%m-%d %H:%M:%S')

Kamlesh Verma

두 작업 사이의 시간을 측정하는 방법. 두 작업의 시간을 비교합니다.

 import time b = (123*321)*123 t1 = time.time() c = ((9999^123)*321)^123 t2 = time.time() print(t2-t1)

7.987022399902344e-05


Wojciech Moszczyński

print_elapsed_time 함수는 다음과 같습니다.

 def print_elapsed_time(prefix=''): e_time = time.time() if not hasattr(print_elapsed_time, 's_time'): print_elapsed_time.s_time = e_time else: print(f'{prefix} elapsed time: {e_time - print_elapsed_time.s_time:.2f} sec') print_elapsed_time.s_time = e_time

이런 식으로 사용

 print_elapsed_time() .... heavy jobs ... print_elapsed_time('after heavy jobs') .... tons of jobs ... print_elapsed_time('after tons of jobs')

결과는

 after heavy jobs elapsed time: 0.39 sec after tons of jobs elapsed time: 0.60 sec

이 기능의 장단점은 시작 시간을 전달할 필요가 없다는 것입니다.


Myeongsik Joo

나는 이것을 위해 라이브러리를 만들었습니다. 함수를 측정하려면 다음과 같이 할 수 있습니다.

 from pythonbenchmark import compare, measure import time a,b,c,d,e = 10,10,10,10,10 something = [a,b,c,d,e] @measure def myFunction(something): time.sleep(0.4) @measure def myOptimizedFunction(something): time.sleep(0.2) myFunction(input) myOptimizedFunction(input)

https://github.com/Karlheinzniebuhr/pythonbenchmark


Karl

질문에서 엄격하게 묻는 것은 아니지만 여러 코드 줄 사이의 경과 시간을 점진적으로 측정하는 간단하고 균일한 방법을 원하는 경우가 많습니다.

Python 3.8 이상을 사용하는 경우 할당 표현식 (일명 바다코끼리 연산자)을 사용하여 상당히 우아한 방식으로 이를 달성할 수 있습니다.

 import time start, times = time.perf_counter(), {} print("hello") times["print"] = -start + (start := time.perf_counter()) time.sleep(1.42) times["sleep"] = -start + (start := time.perf_counter()) a = [n**2 for n in range(10000)] times["pow"] = -start + (start := time.perf_counter()) print(times)

=>

 {'print': 2.193450927734375e-05, 'sleep': 1.4210970401763916, 'power': 0.005671024322509766}

Lee Netherton

import time def getElapsedTime(startTime, units): elapsedInSeconds = time.time() - startTime if units == 'sec': return elapsedInSeconds if units == 'min': return elapsedInSeconds/60 if units == 'hour': return elapsedInSeconds/(60*60)

Sky

이 고유한 클래스 기반 접근 방식은 인쇄 가능한 문자열 표현, 사용자 지정 가능한 반올림 및 경과 시간에 대한 편리한 액세스를 문자열 또는 부동 소수점으로 제공합니다. Python 3.7로 개발되었습니다.

 import datetime import timeit class Timer: """Measure time used.""" # Ref: https://stackoverflow.com/a/57931660/ def __init__(self, round_ndigits: int = 0): self._round_ndigits = round_ndigits self._start_time = timeit.default_timer() def __call__(self) -> float: return timeit.default_timer() - self._start_time def __str__(self) -> str: return str(datetime.timedelta(seconds=round(self(), self._round_ndigits)))

용법:

 # Setup timer >>> timer = Timer() # Access as a string >>> print(f'Time elapsed is {timer}.') Time elapsed is 0:00:03. >>> print(f'Time elapsed is {timer}.') Time elapsed is 0:00:04. # Access as a float >>> timer() 6.841332235 >>> timer() 7.970274425

Asclepius

출처 : http:www.stackoverflow.com/questions/7370801/how-to-measure-elapsed-time-in-python

반응형