파이썬 프로그램 실행 시간 측정하기
왜 실행 시간을 측정해야 할까요?
- 코드 최적화: 코드의 효율성을 분석하고, 더 빠르게 실행되도록 개선하기 위해 필요합니다.
- 성능 비교: 서로 다른 알고리즘이나 데이터 구조의 성능을 비교하여 최적의 방법을 선택할 수 있습니다.
- 병목 현상 찾기: 프로그램에서 가장 많은 시간을 소비하는 부분을 찾아 집중적으로 개선할 수 있습니다.
파이썬에서 실행 시간 측정하는 방법
time 모듈 사용하기
- time.time() 함수:
- 현재 시간을 초 단위의 부동소수점 숫자로 반환합니다.
- 코드 실행 전후에 시간을 측정하여 두 값의 차이를 계산하면 실행 시간을 얻을 수 있습니다.
import time
start_time = time.time()
# 측정하고 싶은 코드
end_time = time.time()
elapsed_time = end_time - start_time
print("실행 시간:", elapsed_time, "초")
- time.perf_counter() 함수:
- 고해상도 타이머를 사용하여 더 정확한 시간 측정이 가능합니다.
- 주로 프로세서 시간을 측정하며, 운영체제나 다른 프로세스의 간섭에 덜 민감합니다.
- timeit.timeit() 함수:
- 특정 코드를 반복 실행하고 평균 실행 시간을 측정합니다.
- 짧은 코드의 실행 시간을 정확하게 측정하는 데 유용합니다.
import timeit
def my_function():
# 측정하고 싶은 코드
elapsed_time = timeit.timeit(my_function, number=1000) # 함수를 1000번 실행
print("평균 실행 시간:", elapsed_time, "초")
cProfile 모듈 사용하기
- cProfile.run() 함수:
- 함수별 실행 시간을 상세하게 프로파일링합니다.
- 코드의 각 부분이 얼마나 많은 시간을 소비하는지 분석하여 병목 현상을 찾는 데 도움이 됩니다.
import cProfile
cProfile.run('my_function()')
%timeit 매직 명령 (Jupyter Notebook)
- Jupyter Notebook에서 간편하게 코드 셀의 실행 시간을 측정할 수 있습니다.
%timeit my_function()
주의 사항
- 측정 환경: 컴퓨터 사양, 운영체제, 파이썬 버전 등에 따라 실행 시간이 달라질 수 있습니다.
- 코드 최적화: 실행 시간 측정 결과를 바탕으로 코드를 최적화할 때는, 알고리즘, 데이터 구조, 라이브러리 선택 등 다양한 요소를 고려해야 합니다.
- 반복 측정: 한 번의 측정 결과만으로는 정확한 평가가 어려울 수 있으므로, 여러 번 측정하여 평균값을 구하는 것이 좋습니다.
예시
import time
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
start_time = time.time()
result = factorial(1000)
end_time = time.time()
print("실행 시간:", end_time - start_time, "초")
print("결과:", result)
파이썬 프로그램 실행 시간 측정 샘플 코드
다양한 상황에 맞춰 활용할 수 있는 파이썬 프로그램 실행 시간 측정 샘플 코드를 몇 가지 준비했습니다.
간단한 함수 실행 시간 측정 (time 모듈)
import time
def my_function(n):
# 측정하고 싶은 코드 (예: 팩토리얼 계산)
result = 1
for i in range(1, n+1):
result *= i
return result
# 시작 시간 기록
start_time = time.time()
# 함수 호출
result = my_function(1000)
# 종료 시간 기록하고 실행 시간 계산
end_time = time.time()
elapsed_time = end_time - start_time
print("실행 시간:", elapsed_time, "초")
print("결과:", result)
다양한 함수에 적용 가능한 데코레이터
import time
def measure_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.tim e()
print(f"실행 시간: {func.__name__} 함수, {end_time - start_time:.4f} 초")
return result
return wrapper
@measure_time
def my_function(n):
# 측정하고 싶은 코드
# ...
# 함수 호출
my_function(1000)
짧은 코드 조각의 정확한 측정 (timeit 모듈)
import timeit
def my_function():
# 측정하고 싶은 코드
# ...
# 함수를 1000번 반복 실행하고 평균 시간 측정
elapsed_time = timeit.timeit(my_function, number=1000)
print("평균 실행 시간:", elapsed_time, "초")
함수별 실행 시간 상세 분석 (cProfile 모듈)
import cProfile
def my_function():
# 측정하고 싶은 코드
# ...
cProfile.run('my_function()')
Jupyter Notebook에서 간편하게 측정 (%timeit 매직 명령)
%timeit my_function()
각 샘플 코드의 특징:
- 1번: 가장 기본적인 방법으로, 시작 시간과 종료 시간을 기록하여 실행 시간을 계산합니다.
- 2번: 데코레이터를 사용하여 함수에 실행 시간 측정 기능을 추가합니다. 여러 함수에 재사용하기 좋습니다.
- 3번:
timeit
모듈을 사용하여 짧은 코드 조각의 실행 시간을 정확하게 측정합니다. - 4번:
cProfile
모듈을 사용하여 함수별 실행 시간을 상세하게 분석합니다. 코드의 병목 현상을 찾는 데 유용합니다.
어떤 코드를 사용할지는 측정 목적과 코드의 복잡도에 따라 달라집니다.
- 간단한 함수의 실행 시간: 1번 또는 2번
- 짧은 코드 조각의 정확한 측정: 3번
- 코드의 병목 현상 찾기: 4번
- Jupyter Notebook 환경: 5번
더 자세한 설명과 다양한 예시는 다음 자료를 참고하세요:
추가적으로 다음과 같은 정보를 제공해주시면 더욱 맞춤형 샘플 코드를 제공해 드릴 수 있습니다:
- 측정하고 싶은 코드: 어떤 종류의 코드인가요? (예: 알고리즘, 데이터 처리, 웹 스크래핑 등)
- 측정 목적: 왜 실행 시간을 측정하고 싶나요? (예: 코드 최적화, 성능 비교, 병목 현상 찾기 등)
- 사용하는 개발 환경: 어떤 IDE나 텍스트 편집기를 사용하시나요? Jupyter Notebook을 사용하시나요?
파이썬 프로그램 실행 시간 측정: 더 다양한 방법과 고급 기능
앞서 소개해 드린 기본적인 방법 외에도 파이썬에서는 더욱 정교하고 다양한 방법으로 프로그램 실행 시간을 측정할 수 있습니다.
프로파일링 도구 활용
- line_profiler: 특정 함수 내에서 각 라인별 실행 시간을 측정하여 병목 현상을 더욱 정확하게 파악할 수 있습니다.
- memory_profiler: 메모리 사용량을 측정하여 메모리 누수 등의 문제를 진단합니다.
- Pyinstrument: 웹 기반 프로파일러로, 시각적으로 매력적인 프로파일링 결과를 제공합니다.
예시 (line_profiler):
import line_profiler
@profile
def my_function(n):
# 측정하고 싶은 코드
# ...
my_function(1000)
설치: pip install line_profiler
시간 단위 조절
- time.perf_counter_ns(): 나노초 단위의 고정밀 시간 측정
- time.process_time(): 프로세서 사용 시간 측정 (I/O 시간 제외)
예시:
import time
start_time = time.perf_counter_ns()
# 측정하고 싶은 코드
end_time = time.perf_counter_ns()
print("실행 시간:", (end_time - start_time) / 1e9, "초")
외부 라이브러리 활용
- pandas.Timedelta: 시간 차이를 나타내는 객체를 생성하여 더욱 유연한 시간 계산 가능
- NumPy: 벡터화 연산을 통해 빠른 시간 측정 가능
다중 코어 환경에서의 측정
- multiprocessing: 병렬 처리 시 각 프로세스의 실행 시간 측정
- concurrent.futures: 스레드 또는 프로세스를 이용한 비동기 작업 실행 시간 측정
특정 이벤트 기반 측정
- logging: 로그를 기록하여 특정 이벤트 발생 시점을 기록
- custom decorators: 함수 실행 전후에 특정 작업을 수행하는 데코레이터를 정의하여 시간 측정
외부 도구 활용
- gprof: GNU 프로파일러
- perf: 리눅스 커널 프로파일러
어떤 방법을 선택해야 할까요?
- 정확성: 나노초 단위의 정확성이 필요하다면
time.perf_counter_ns()
를 사용합니다. - 간단한 측정:
time.time()
이나timeit
모듈이 충분합니다. - 병목 현상 찾기:
line_profiler
나cProfile
을 사용합니다. - 메모리 사용량 측정:
memory_profiler
를 사용합니다. - 시각화: Pyinstrument를 사용합니다.
- 다중 코어 환경:
multiprocessing
이나concurrent.futures
를 사용합니다.
주의 사항:
- 측정 오버헤드: 측정 코드 자체가 실행 시간에 영향을 줄 수 있으므로, 간단한 코드일수록 측정 오버헤드가 상대적으로 커질 수 있습니다.
- 환경 변수: 시스템 환경 설정에 따라 측정 결과가 달라질 수 있습니다.
- "특정 함수 내에서 가장 시간이 오래 걸리는 부분을 찾고 싶습니다. 어떤 방법을 사용해야 할까요?"
- "다중 코어를 활용하여 프로그램을 실행할 때, 각 코어의 실행 시간을 측정하고 싶습니다."
- "메모리 누수가 의심됩니다. 메모리 사용량을 측정하는 방법을 알려주세요."
python time execution-time