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.