본문 바로가기
Python/Python Advanced

7. Python - timeit모듈, timeit()매서드로 코드 실행시간 계산하기

by Rosmary 2021. 5. 12.
728x90
반응형

 

 

 

 

 

Python으로 코드를 작성하다보면, 내가 작성한 코드가 얼마나 빠르게 동작하는지 궁금할 때가 있다. 코드의 실행시간이 짧다는 것은, 그만큼 코드가 효율적으로 작성되어 있다는 것이기 때문이다. 프로그램을 막 시작한 초보자라면, 특히 프로그램의 효율적인 동작에 관심이 많은 경우라면, 자신이 작성한 프로그램에 대해 수행 시간을 측정해보려고 시도해보았을 것이다.

 

하나 예를 들어보자. 1부터 10000000까지의 합을 구하는 코드를 작성한다고 해보자. 이를 구하기 위해 사용할 수 있는 Python 문법으로는 크게 for나 while 루프문이 있다. 과연 어떤 방법이 더 빠를까? 이를 확인하기 위해, 프로그램을 막 배우기 시작하신 분들은 대다수가 아래와 같은 코드로 작성할 것이라 생각한다.

 

 

 

 

각 함수 내에 time 모듈의 Method를 사용하여 함수 시작 시간과 끝 시간을 측정하고, 그 차이를 화면에 출력하는 방식을 많이 사용할 것이다.

 

 

for 문이 더 빠르다. 0.3초 정도

 

 

그런데, 코드 수행 시간을 측정해야 할 구간이 무진장 늘어난다면, start_time = time.time(), end_time = time.time(), print(end_time - start_time) 코드를 모든 함수 또는 수행 코드의 앞 뒤에 추가해야 하는 문제가 발생한다. 설령 모든 측정 구간에 대해 이 코드들을 모두 다 넣어준다고 해도, 나중에는 이 코드들을 모두 삭제해야하는데, 삭제하는 과정에서 반드시 필요한 코드들도 지워버릴 위험성도 존재한다.

 

이런 문제 때문에, Python에서는 timeit이라는 모듈을 기본으로 제공하고 있다. timeit 모듈 내에는 timeit이라는 동일한 이름의 메서드가 존재하는데, 이 메서드는 특정 코드 또는 함수의 실행 시간을 측정하고 그 값을 반환하는 역할을 한다. 

 

timeit() 메서드는 아래와 같은 구조로 되어 있다.

 

timeit (stmt, setup, timer, number, globals)

 

(1)  stmt :  수행 시간을 측정하고자 하는 코드나 함수명을 입력해주면 된다. 직접 코드를 명시하는 경우, stmt="코드"를 작성해주면 되고, 함수의 경우 별도의 따옴표 없이 stmt 매개변수값에 지정해주면 된다.

 

print("hello world")의 수행시간을 timeit() 메서드로 측정하고자 한다면 아래와 같이 나타낼 수 있다. 

 

 

 

 

만약, 함수를 하나 작성하여 함수 실행 시간을 측정하는 경우, 아래와 같이 나타낼 수 있다.

 

 

 

 

 

(2) Number

 

위의 예시 코드를 잘 보면, 필자가 number 매개변수를 1로 설정해 둔 것을 확인할 수 있다. 사실 이 number는 기본값이 지정된 매개변수라 없어도 코드를 실행하는데 큰 문제는 없다. 이 number 매개변수는, 수행 시간 측정을 위해, 코드나 함수를 몇 번 반복하여 실행할 것인지 설정한다고 보면 된다. 만약 number에 대해 별도의 값을 지정해주지 않는다면, print("hello world")는 백만 번(10^6) 수행한 시간에 대해 표시하게 된다. 

 

timeit('print ("Hello World")) 의 결과는 아래와 같이 나온다.

 

 

생각보다 오래 걸린다.

 

단순한 print 함수를 백만 번 수행하는데도 1분이 넘는 시간이 걸린다. 따라서 timeit 함수를 사용하여 코드 수행 시간을 측정할 때 필자는 number 매개변수를 반드시 설정하고 실행할 것을 권고한다.

 

 

(3) setup

 

만약, 1부터 n까지 숫자를 배열에 저장하는 for 문 코드를 바로 timeit 함수에 적용하여 수행 시간을 측정한다고 해보자. 아래와 깉이 timeit 함수를 작성할 수 있을 것이다.

 

timeit("[number for number in range(1, n)]", number = 1)

 

하지만 위와 같이 코드를 작성할 경우, n에 대한 정보가 없기 때문에 아래와 같이 오류가 나게 된다.

 

 

 

그럼 timeit 매서드에서 이 n값을 인식하게 할 수 있는 방법이 있을까? 이를 위해 사용하는 것이 timeit() 매서드의 setup매개변수다. setup 매개변수는 수행하는 코드에 필요한 내용을 정의하는 부분이라고 보면 된다. 우리가 코드 수행 시간 측정을 위해 필요한 변수 n이 정의되어야하므로, setup 매개변수를 아래와 같이 작성하여 timeit() 매서드를 실행해주면 된다.

 

timeit("[number for number in range(1, n)]", setup="n=100", number = 1)

 

 

 

 

만약 함수명을 stmt 매개변수에서 따옴표 등으로 감싸서 작성하게되는 경우, 위의 for 문 timeit 매서드 실행 결과와 동일한 에러를 볼 수 있는데, 그 이유는 stmt의 따옴표 내에 정의된 함수를 하나의 코드로 인식하기 때문이다.

 

 

number_save_in_list() 코드가 무엇인지 모르겠다는 Python Interpreter의 푸념이 보인다.

 

 

따라서 setup에 이 number_save_in_list() 함수를 인식할 수 있도록 "from __main__ import number_save_in_list"를 추가해 주어야 한다. 이 파일에서 number_save_in_list를 import하면 Python 인터프리터가 number_save_in_list()가 무엇인지 알 수 있기 때문이다.

 

 

 

 

 

(4) timerglobals

 

timer 변수는 timeit.Timer() 객체 값을 사용하는 매개변수다. timeit의 Timer() 매서드도 timeit() 매서드와 동일한 역할을 하는 녀석이지만, Python이 업데이트 되면서 이 객체를 기본 매개변수값으로 사용하는 듯 하다. 영어로 작성된 정보를 찾아보니, 크게 신경써야되는 매개변수는 아닌 듯 하다.

 

globals도 timeit() 매서드 수행에 있어서 필수로 작성해야 하는 매개변수가 아닌데다, 없어도 동작에 무리가 없는 매개변수다. 기본값을 None값으로 사용하기 때문에, 이 매개변수도 크게 신경쓰지 않아도 될 듯 하다.

 

 


이번 포스팅에서는 timeit 모듈을 이용하여, 특정 구간의 함수 수행 시간을 측정하는 방법에 대해 알아보았다. time 모듈을 사용하는 방법도 나쁘지 않은 방법이지만, 서두에 설명한 것처럼 여러 구간에서의 수행 시간 측정에는 무리가 있다. 필자는 요즘 프로그래밍을 하면서 이 timeit 모듈을 많이 사용하는데, timeit 모듈에 익숙해지니 확실히 수행 시간 측정에 투입되는 시간 자체가 많이 줄어든 것을 느끼고 있다.

 

 

 

Fin.

반응형

댓글