텍스트 전처리나 모델링을 할 때 시간이 소요되는데, 성능을 모니터링 하기 위해 파이썬의 프로파일링 도구를 이용하고 있다. 시스템 명령어인 time, 파이썬 모듈인 timeit, cProfile, prun, lprun, mprun 을 알아보자.
벤치마크 실행 시간 측정
time
프로세스의 전체 실행 시간은 time 유닉스 명령어를 사용해 측정할 수 있다.
$ time python simul.py
real 0m1.051s
user 0m1.022s
sys 0m0.028s
Real: 프로세스 시작부터 종료까지 걸리는 시간 (I/O, 다른 프로세스 대기 시간 포함)
User: CPU가 연산 수행에 할애한 전체 시간
Sys: 시스템 관련 연산 및 메모리 할당에 CPU가 할애한 시간
여러 프로세서가 병렬로 연산을 수행할 경우 user와 sys의 합이 real보다 클 수 있다.
Timeit 모듈
파이선 스크립트 실행 시간 측정 대상코드를 n번 실행한 뒤 평균 실행 시간 계산한다. 이 작업을 r번 반복 후 최적의 결과를 출력한다. 프로그램 내 특정 부분의 실행 시간을 독립적으로 측정할 때 유용하다. 커맨드 라인 또는 IPython 셀에서 사용 가능하다.
cProfile을 사용해 병목지점 찾기
파이썬 라이브러리에서 제공하는 세 가지 프로파일링 모듈이다.
-
Profile: 표준 라이브러리에 포함되어 있긴 하지만 실행 시 오버헤드가 크다
-
Hotshot: C 모듈이라 오버헤드가 가장 적다.
-
cProfile: 다목적 프로파일링에 적합하고 오버헤드가 매우 적다.
$ python -m cProfile simul.py
$ python -m cProfile -s tottime simul.py
$ python -m cProfile -o prof.out simul.py
prun
In IPython
%prun
Line_profiler를 사용한 라인 프로파일링
함수 별 실행시간 측정 가능하다. 측정하려는 함수 앞에 @profiler 수식어를 붙이면 line_profiler 가 자동으로 활성화 된다. 커맨드라인으로 실행 시 -l 옵션으로 프로파일링을 키고 끌 수 있다.
$ kernprof.py -l -v simul.py
lprun
In IPython
% lprun
Dis 모듈
특정 파이썬 코드가 실행될 때 내부적으로 어떤 구조로 실행되는 지 볼 수 있다. Disassemble 모듈을 의미하고, 파이썬 코드가 바이트코드로 변환되는 과정을 관찰할 수 있다.
Import dis from simul
dis.dis(func)
func 각 줄에 대응하는 바이트코드를 출력한다.
#Memory_profiler를 사용한 메모리 사용 프로파일링
mprun
프로세스의 메모리 사용량을 요약하여 출력한다. 메모리 오버헤드를 관측할 수 있다. Line_profiler 와 비슷하게 @profile 수식어를 추가하여 활성화 할 수 있다.
In IPython
%load_ext memory_profiler
%mprun -f func()
그 외의 파이썬 코드 튜닝 팁
우선 표준 라이브러리에서 사용할 만한 모듈이 있다면 사용을 권장한다. C 기반으로 실행 속도가 빠르기 때문이다.
참고문헌
Lanaro, G. (2013). Python high performance programming : boost the performance of your Python programs using advanced techniques. Packt Pub.