파이썬 timeit 모듈 완벽 가이드: 코드 실행 시간 측정
본 튜토리얼에서는 파이썬의 timeit 모듈 내 timeit 함수 활용법을 자세히 살펴봅니다. 파이썬 코드 조각과 함수의 실행 시간을 정확하게 측정하는 방법을 단계별로 안내합니다.
코드 실행 시간 측정은 프로그램의 특정 부분이 얼마나 오래 걸리는지 파악하고, 최적화가 필요한 부분을 찾아내는 데 매우 유용합니다. 이를 통해 코드의 효율성을 높이고 전반적인 성능을 개선할 수 있습니다.
먼저 timeit 함수의 기본 구문과 사용법을 알아보고, 다양한 예제를 통해 파이썬 코드의 실행 시간을 측정하는 방법을 익혀보겠습니다. 이제 시작해 볼까요?
timeit 함수 사용법
timeit 모듈은 파이썬 표준 라이브러리에 포함되어 있어 다음과 같이 간편하게 가져올 수 있습니다.
import timeit
timeit 모듈의 핵심인 timeit 함수의 구문은 다음과 같습니다.
timeit.timeit(stmt, setup, number)
각 매개변수의 의미는 다음과 같습니다.
- stmt: 실행 시간을 측정하려는 코드 조각입니다. 간단한 파이썬 문자열, 여러 줄 문자열, 또는 호출 가능한 객체의 이름을 사용할 수 있습니다.
- setup: stmt 실행 전에 한 번만 실행되어야 하는 설정 코드입니다. 예를 들어, NumPy 배열 생성 시간을 측정하는 경우, NumPy 가져오기는 설정 코드가 되고 실제 배열 생성 코드는 stmt가 됩니다.
- number: stmt를 실행할 횟수입니다. 기본값은 100만(1000000)이지만 원하는 값으로 설정할 수 있습니다.
timeit() 함수의 사용법을 익혔으니, 몇 가지 예제를 통해 실제 코드에 적용해 보겠습니다.
간단한 파이썬 표현식 시간 측정
이 섹션에서는 timeit을 사용하여 간단한 파이썬 표현식의 실행 시간을 측정해 보겠습니다.
파이썬 REPL을 시작하고 다음 예제 코드를 실행해 보세요. 여기서는 10000번 및 100000번 실행 시 지수 연산과 몫 연산의 실행 시간을 측정합니다.
timeit 함수에 측정할 명령문을 파이썬 문자열로 전달하고, 명령문 내에서 다른 표현식을 구분하기 위해 세미콜론을 사용합니다.
>>> import timeit >>> timeit.timeit('3**4;3//4',number=10000) 0.0004020999999738706 >>> timeit.timeit('3**4;3//4',number=100000) 0.0013780000000451764
명령줄에서 timeit 실행
timeit은 명령줄에서도 사용할 수 있습니다. 다음은 timeit 함수 호출에 해당하는 명령줄 구문입니다.
$ python -m timeit -n [number] -s [setup] [stmt]
python -m timeit
은 timeit을 모듈로 실행한다는 의미입니다.-n
옵션은 코드를 실행해야 하는 횟수를 지정합니다. 이는 timeit() 함수의 number 인수와 같습니다.-s
옵션을 사용하여 설정 코드를 정의할 수 있습니다.
다음은 명령줄에서 이전 예제를 다시 실행한 결과입니다.
$ python -m timeit -n 100000 '3**4;3//4'
100000 loops, best of 5: 35.8 nsec per loop
이 예제에서는 내장 함수 len()의 실행 시간을 측정합니다. 문자열 초기화는 -s 옵션으로 전달되는 설정 코드입니다.
$ python -m timeit -n 100000 -s "string_1 = 'coding'" 'len(string_1)'
100000 loops, best of 5: 239 nsec per loop
출력 결과를 보면 최고 5회 실행에 대한 실행 시간을 얻을 수 있습니다. 이는 명령줄에서 timeit을 실행할 때 반복 옵션 -r이 기본값 5로 설정되어 있기 때문입니다. 즉, 지정된 횟수만큼 stmt를 5번 실행하고, 그 중 가장 빠른 실행 시간을 반환합니다.
timeit을 이용한 문자열 반전 방법 비교 분석
파이썬에서 문자열을 처리할 때 문자열을 뒤집어야 하는 경우가 종종 있습니다. 문자열 반전에 대한 가장 일반적인 두 가지 방법은 다음과 같습니다.
- 문자열 슬라이싱 사용
- reversed() 함수 및 join() 메서드 사용
문자열 슬라이싱을 이용한 문자열 반전
문자열 슬라이싱이 어떻게 작동하며, 이를 사용하여 파이썬 문자열을 반전시키는 방법을 살펴보겠습니다. some-string[start:stop]
구문은 시작 인덱스에서 시작하여 종료 인덱스 – 1까지 확장되는 문자열 조각을 반환합니다. 예를 들어 문자열 ‘Python’을 생각해 봅시다.
문자열 ‘Python’의 길이는 6이며, 인덱스는 0, 1, 2부터 5까지입니다.
>>> string_1 = 'Python'
시작 값과 종료 값을 모두 지정하면 시작부터 종료 – 1까지 확장되는 문자열 슬라이스가 생성됩니다. 따라서 string_1[1:4]
는 ‘yth’를 반환합니다.
>>> string_1 = 'Python' >>> string_1[1:4] 'yth'
시작 값을 지정하지 않으면 기본 시작 값 0이 사용되고, 슬라이스는 인덱스 0부터 시작하여 종료 – 1까지 확장됩니다.
여기서 종료 값은 3이므로 슬라이스는 인덱스 0에서 시작하여 인덱스 2까지 확장됩니다.
>>> string_1[:3] 'Pyt'
종료 인덱스를 생략하면 슬라이스가 시작 인덱스(1)에서 시작하여 문자열 끝까지 확장되는 것을 알 수 있습니다.
>>> string_1[1:] 'ython'
시작 값과 종료 값을 모두 생략하면 전체 문자열의 조각이 반환됩니다.
>>> string_1[::] 'Python'
단계 값을 사용하여 슬라이스를 만들어 보겠습니다. 시작, 종료, 단계 값을 각각 1, 5, 2로 설정합니다. 그러면 1에서 시작하여 모든 두 번째 문자를 포함하는 최대 4(끝점 5 제외)까지 확장되는 문자열 슬라이스를 얻습니다.
>>> string_1[1:5:2] 'yh'
음수 단계를 사용하면 문자열 끝에서 시작하는 슬라이스를 얻을 수 있습니다. 단계를 -2로 설정하면 string_1[5:2:-2]
는 다음 슬라이스를 제공합니다.
>>> string_1[5:2:-2] 'nh'
따라서 문자열의 반전된 복사본을 얻으려면 시작 및 종료 값을 생략하고 단계를 -1로 설정합니다.
>>> string_1[::-1] 'nohtyP'
요약하자면, 문자열[::-1]
은 문자열의 반전된 복사본을 반환합니다.
내장 함수 및 문자열 메소드를 이용한 문자열 반전
파이썬의 내장 함수인 reversed() 함수는 문자열 요소에 대한 역 반복자를 반환합니다.
>>> string_1 = 'Python' >>> reversed(string_1) <reversed object at 0x00BEAF70>
따라서 for 루프를 사용하여 역 반복자를 반복할 수 있습니다.
for char in reversed(string_1): print(char)
그리고 역순으로 문자열의 요소에 액세스할 수 있습니다.
# 출력 n o h t y P
그런 다음 .join(reversed(some-string))
구문을 사용하여 역 반복자에서 join() 메서드를 호출할 수 있습니다.
아래 코드 스니펫은 구분 기호가 하이픈과 공백인 몇 가지 예제를 보여줍니다.
>>> '-'.join(reversed(string1)) 'n-o-h-t-y-P' >>> ' '.join(reversed(string1)) 'n o h t y P'
여기서는 구분 기호를 원하지 않습니다. 따라서 문자열의 반전된 복사본을 얻으려면 구분 기호를 빈 문자열로 설정해야 합니다.
>>> ''.join(reversed(string1)) 'nohtyP'
''.join(reversed(some-string))
를 사용하면 문자열의 반전된 복사본이 반환됩니다.
timeit을 이용한 실행 시간 비교
지금까지 파이썬 문자열을 반전시키는 두 가지 방법을 알아보았습니다. 그렇다면 이 두 가지 방법 중 어느 것이 더 빠를까요? 한번 알아보도록 하겠습니다.
간단한 파이썬 표현식의 실행 시간을 측정한 이전 예제에서는 설정 코드가 없었습니다. 여기서는 파이썬 문자열을 반전시키는 작업을 합니다. 문자열 반전 작업이 number로 지정된 횟수 동안 실행되는 동안 설정 코드는 문자열 초기화처럼 한 번만 실행되는 코드입니다.
>>> import timeit >>> timeit.timeit(stmt="string_1[::-1]", setup = "string_1 = 'Python'", number = 100000) 0.04951830000001678 >>> timeit.timeit(stmt = "''.join(reversed(string_1))", setup = "string_1 = 'Python'", number = 100000) 0.12858760000000302
위 결과를 통해 문자열을 뒤집는 동일한 횟수 실행 시 문자열 슬라이싱 방식이 join() 메서드와 reversed() 함수를 사용하는 것보다 더 빠르다는 것을 확인할 수 있습니다.
timeit을 활용한 파이썬 함수 실행 시간 측정
이 섹션에서는 timeit 함수를 사용하여 파이썬 함수의 실행 시간을 측정하는 방법을 알아보겠습니다. 문자열 목록이 주어지면 다음 hasDigit 함수는 적어도 하나의 숫자가 포함된 문자열 목록을 반환합니다.
def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit
이제 timeit을 사용하여 이 파이썬 함수 hasDigit()의 실행 시간을 측정해 보겠습니다.
먼저 시간을 측정할 명령문(stmt)을 식별해 보겠습니다. 여기서는 문자열 목록을 인수로 사용하여 hasDigit() 함수를 호출합니다. 다음으로 설정 코드를 정의해 보겠습니다. 설정 코드에 무엇이 포함되어야 할까요?
함수 호출이 성공적으로 실행되려면 설정 코드에 다음이 포함되어야 합니다.
- 함수 hasDigit()의 정의
- 문자열 인수를 담은 목록의 초기화
아래와 같이 설정 문자열에 설정 코드를 정의해 보겠습니다.
setup = """ def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit thislist=['puffin3','7frost','blue'] """
다음으로 timeit 함수를 사용하여 100000번 실행 시 hasDigit() 함수의 실행 시간을 측정해 보겠습니다.
import timeit timeit.timeit('hasDigit(thislist)',setup=setup,number=100000)
# 출력 0.2810094920000097
결론
이 튜토리얼에서는 파이썬의 timeit 함수를 사용하여 표현식, 함수 및 기타 호출 가능한 객체의 실행 시간을 측정하는 방법을 배웠습니다. 이를 통해 코드의 성능을 벤치마킹하고 동일한 기능에 대한 여러 구현의 실행 시간을 비교하는 등의 작업을 수행할 수 있습니다.
이 튜토리얼에서 배운 내용을 다시 한번 정리해 보겠습니다. timeit() 함수는 timeit.timeit(stmt=...,setup=...,number=...)
구문으로 사용할 수 있습니다. 또는 짧은 코드 조각의 실행 시간을 측정하기 위해 명령줄에서 timeit을 실행할 수 있습니다.
다음 단계로 line-profiler 및 memprofiler와 같은 다른 파이썬 프로파일링 패키지를 사용하여 각각 시간 및 메모리 사용에 대한 코드를 프로파일링하는 방법을 탐색할 수 있습니다.
이 다음에는 파이썬에서 시간차를 계산하는 방법을 배우게 될 것입니다.