Python 2.7에서 코드 블록 실행 시간 가져 오기


78

사용자 CPU 시간, 시스템 CPU 시간 및 경과 시간을 구분하여 Python 프로그램의 코드 블록을 평가하기 위해 경과 된 시간을 측정하고 싶습니다.

timeit모듈을 알고 있지만 자체 작성 기능이 많고 설정 프로세스에서 전달하기가 쉽지 않습니다.

차라리 다음과 같이 사용할 수있는 것이 있습니다.

#up to here I have done something....
start_counting() #or whatever command used to mark that I want to measure
                   #the time elapsed in the next rows
# code I want to evaluate
user,system,elapsed = stop_counting() #or whatever command says:
                                      #stop the timer and return the times

사용자 및 시스템 CPU 시간은 필수는 아니지만 (측정하고 싶지만), 경과 시간 동안 복잡한 명령이나 모듈을 사용하는 대신 이와 같은 작업을 수행 할 수 있기를 바랍니다.

답변:


167

경과 시간을 초 단위로 얻으려면 다음을 사용할 수 있습니다 timeit.default_timer().

import timeit
start_time = timeit.default_timer()
# code you want to evaluate
elapsed = timeit.default_timer() - start_time

timeit.default_timer()대신 time.time()또는 time.clock()모든 플랫폼에 대해 더 높은 해상도를 가진 타이밍 기능을 선택하기 때문에 사용됩니다 .


4
나는 이것이 실행하는 데 몇 초 밖에 걸리지 않는 코드 블록에 대한 최선의 접근 방식이 아니라는 것을 읽었습니다. 또한 시간 모듈을 사용하는 것이 .clock () 메서드가 선호된다고 생각합니까? stackoverflow.com/questions/85451/...
— lucacerone

4
사용 하는 플랫폼에서 더 높은 해상도를 timeit.default_timer()선택 time.time()하거나 선택하는 사용에 대한 내 대답을 변경했습니다 time.clock().
— Andrew Clark

24

나는 항상 데코레이터를 사용하여 실행 시간을 얻는 것을 포함하여 기존 함수에 대한 추가 작업을 수행합니다. 비단뱀적이고 간단합니다.

import time

def time_usage(func):
    def wrapper(*args, **kwargs):
        beg_ts = time.time()
        retval = func(*args, **kwargs)
        end_ts = time.time()
        print("elapsed time: %f" % (end_ts - beg_ts))
        return retval
    return wrapper

@time_usage
def test():
    for i in xrange(0, 10000):
        pass

if __name__ == "__main__":
    test()

3
미안, 난 여전히 장식 :( 사용하는 방법을 모르는거야
— lucacerone

4
@LucaCerone 장식 stackoverflow.com/questions/739654/… 에 대한 훌륭한 설명이 있습니다. 참을성있게 읽으면 데코레이터를 이해할 수있을 것입니다.
— Yarkee

래퍼에 retval=...and return retval를 추가 할 수 있습니다 . 데코레이터를 그대로 사용하면 func의 반환 값이 삭제됩니다.
— Dave X

11

나는이 문제를 몇 번이고 해결하는 것을 발견하고 마침내 그것을 위한 라이브러리 를 만들었 습니다. 로 설치합니다 pip install timer_cm. 그때:

from time import sleep
from timer_cm import Timer

with Timer('Long task') as timer:
    with timer.child('First step'):
        sleep(1)
    for _ in range(5):
        with timer.child('Baby steps'):
            sleep(.5)

산출:

Long task: 3.520s
  Baby steps: 2.518s (71%)
  First step: 1.001s (28%)

내가 제기 한 겉보기 관련 질문 : stackoverflow.com/questions/48260833/…
— lurix66

오타 ( 'import timer'---> 'import Timer')와 누락 된 패키지 ( import time)를 제외하고 훌륭하게 작동합니다.
— user3768495

환상적입니다. 사람들이 가져올 때 선택할 수있는 스텁을 사용하여 저장소에 github 문제를 작성했습니다.
— Craig Ringer

9

예를 들어 Context Manager를 통해이를 수행 할 수 있습니다.

from contextlib import contextmanager
import time
import logging
@contextmanager
def _log_time_usage(prefix=""):
    '''log the time usage in a code block
    prefix: the prefix text to show
    '''
    start = time.time()
    try:
        yield
    finally:
        end = time.time()
        elapsed_seconds = float("%.2f" % (end - start))
        logging.debug('%s: elapsed seconds: %s', prefix, elapsed_seconds)

사용 예 :

with _log_time_usage("sleep 1: "):
    time.sleep(1)

마지막 줄 prefix에는이 아니 어야합니다 item_name .
— George Petrov

1

단순성을 위해 내가 지금 많이 좋아하는 옵션이 하나 더 있습니다 ipython. ipython에는 다음과 같은 유용한 기능이 많이 있습니다.

%time <expression> -표현에 대한 직접적인 CPU와 벽 시간을 얻기 위해

%timeit <expression> -표현의 루프에서 CPU와 벽 시간을 얻기 위해


0

Python 3-표준 라이브러리를 사용한 간단한 솔루션

옵션 1 : 코드를 세 번 인용

import inspect
import timeit


code_block = inspect.cleandoc("""
    base = 123456789
    exponent = 100
    return base ** exponent
    """)
print(f'\Code block: {timeit.timeit(code_block, number=1, globals=globals())} elapsed seconds')

inspect.cleandoc 들여 쓰기 오류없이 코드 블록을 복사하여 붙여 넣을 수 있도록 추가 탭 및 공백 제거를 처리합니다.

 

옵션 2 : 함수에 코드 블록 배치

import timeit


def my_function():
    base = 123456789
    exponent = 100
    return base ** exponent


if __name__ == '__main__':
    print(f'With lambda wrapper: {timeit.timeit(lambda: my_function(), number=1)} elapsed seconds')

함수 호출은 함수 본문을 직접 타이밍하는 대신 추가 실행 시간을 추가합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.