파이썬 프로파일러
파이썬 프로파일러 (The Python Profilers)
cProfile 과 profile 은 파이썬 프로그램의 결정적 프로파일링(deterministic profiling) 을 제공해요. 프로파일 은 프로그램의 다양한 부분이 얼마나 자주, 얼마나 오래 실행됐는지를 설명하는 통계 집합이에요. 이 통계는 pstats 모듈을 통해 보고서로 포맷할 수 있어요.
본문
프로파일러 소개 (Introduction to the profilers)
파이썬 표준 라이브러리는 같은 프로파일링 인터페이스의 두 가지 다른 구현을 제공해요.
cProfile— 대부분의 사용자에게 권장돼요. 합리적인 오버헤드를 가진 C 확장으로, 오래 실행되는 프로그램의 프로파일링에 적합해요.lsprof에 기반했어요.profile— 순수 파이썬 모듈로,cProfile이 그 인터페이스를 흉내 내지만 프로파일링되는 프로그램에 상당한 오버헤드를 추가해요. 프로파일러를 확장하려 한다면 이 모듈이 더 쉬울 수 있어요.
참고: 프로파일러 모듈은 벤치마킹이 아니라 주어진 프로그램의 실행 프로파일을 제공하도록 설계됐어요(벤치마킹에는 timeit 사용). 특히 파이썬 코드를 C 코드와 벤치마킹할 때 프로파일러는 파이썬 코드에는 오버헤드를 더하지만 C 수준 함수에는 더하지 않으므로 C 코드가 어떤 파이썬 코드보다 빠르게 보일 수 있어요.
즉시 사용자 매뉴얼 (Instant User's Manual)
단일 인자를 받는 함수를 프로파일링하려면:
import cProfile
import re
cProfile.run('re.compile("foo|bar")')
(시스템에 cProfile 이 없으면 profile 을 사용하세요.) 이는 re.compile() 을 실행하고 아래 같은 프로파일 결과를 출력해요.
214 function calls (207 primitive calls) in 0.002 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.002 0.002 {built-in method builtins.exec}
1 0.000 0.000 0.001 0.001 <string>:1(<module>)
1 0.000 0.000 0.001 0.001 __init__.py:250(compile)
...
첫 줄은 214번의 호출이 모니터링됐음을 나타내요. 그중 207번은 재귀로 유발되지 않은 원시(primitive) 호출이에요. 열 제목의 의미는 다음과 같아요.
ncalls— 호출 수.tottime— 주어진 함수에서 보낸 총 시간(하위 함수 호출 시간 제외).percall—tottime을ncalls로 나눈 몫.cumtime— 이 함수와 모든 하위 함수에서 보낸 누적 시간(호출부터 종료까지). 재귀 함수에서도 정확해요.percall—cumtime을 원시 호출 수로 나눈 몫.filename:lineno(function)— 각 함수의 해당 데이터.
첫 열에 두 숫자(예: 3/1)가 있으면 함수가 재귀했다는 뜻이에요. 두 번째 값은 원시 호출 수이고 첫 번째는 총 호출 수예요. 프로파일 끝에 결과를 출력하는 대신 run() 함수에 파일 이름을 지정해 파일로 저장할 수 있어요:
import cProfile
import re
cProfile.run('re.compile("foo|bar")', 'restats')
pstats.Stats 클래스가 프로파일 결과를 파일에서 읽어 다양한 방식으로 포맷해요.
cProfile 과 profile 은 다른 스크립트를 프로파일링하는 스크립트로도 호출할 수 있어요:
python -m cProfile [-o output_file] [-s sort_order] (-m module | myscript.py)
- -o <output_file> — 프로파일 결과를 stdout 대신 파일에 써요.
- -s <sort_order> — 출력을 정렬할
sort_stats()정렬 값 중 하나를 지정해요. - -m
— 스크립트 대신 모듈을 프로파일링함을 지정해요.
pstats 모듈의 Stats 클래스는 프로파일 결과 파일에 저장된 데이터를 조작·출력하는 다양한 메서드를 가져요:
import pstats
from pstats import SortKey
p = pstats.Stats('restats')
p.strip_dirs().sort_stats(-1).print_stats()
strip_dirs() 는 모든 모듈 이름에서 불필요한 경로를 제거하고, sort_stats() 는 표준 모듈/줄/이름 문자열에 따라 모든 항목을 정렬해요.