파이썬 코드 프로파일링, 이 6가지 라이브러리에 주목해라

파이썬 코드 프로파일링, 이 6가지 라이브러리에 주목해라

코딩월드뉴스 2021-07-30 19:16:09

사진 출처: freepik
사진 출처: freepik

모든 프로그래밍 언어는 두 종류의 '속도'를 가진다. 하나는 개발 속도이고 다른 하나는 실행 속도이다. 파이썬(Python)은 항상 빠른 실행 속도보다 빠른 작성 속도를 선택해왔다. 물론 파이썬 코드는 거의 항상 작업에 대한 충분히 빠른 속도를 지원하지만, 때로는 그렇지 않을 때가 있다. 파이썬의 동작 속도가 느리다면 어떤 곳에서 속도 지연이 발생했는지 원인을 파악해서 해결해야 한다.

소프트웨어 개발 및 엔지니어링에는 "추측하지 말고 측정해라"라는 말이 있다. 소프트웨어에서 문제점이 무엇인지 쉽게 추측해볼 수 있지만, 이는 좋은 방법이 아니다. 실제 프로그램 성능에 대한 통계를 활용하는 것이 애플리케이션을 항상 더 빠르게 만드는 최고의 방법이다.

파이썬은 응용 프로그램을 프로파일링하고 가장 느린 부분을 학습할 수 있도록 다양한 패키지를 제공한다. 여기에 표준 라이브러리에 포함된 간단한 단일 라인에서 실행 중인 응용프로그램에서 통계를 수집하기 위한 정교한 프레임워크에 이르기까지 다양한 도구가 있다. 인포월드가 교차 플랫폼을 실행할 수 있고, PYPI 또는 파이썬 표준 라이브러리에서 쉽게 사용할 수 있는 6가지 라이브러리를 소개했다.

1. Time and Timeit
가끔은 '스톱워치'처럼 간단한 기능만 필요할 때가 있다. 몇 초 또는 몇 분이 걸리는 두 코드 조각 사이의 시간을 프로파일링하는 것만으로 충분하다면 스톱워치 기능이면 충분하다.

파이썬 표준 라이브러리는 스톱워치로 작동하는 두 가지 기능을 제공한다. 시간 모듈에 있는 perf_counter 함수는 운영체제의 고해상도 타이머를 호출해 임의의 타임 스탬프를 가져온다. time.perf_counter를 작업 전에 한 번, 작업 후에 한 번 호출하면 둘 사이의 차이를 구한다. 이를 통해 눈에 띄지 않고 오버헤드가 낮으며 간단한 방식으로 시간 코드를 지정할 수 있다.

Timeit 모듈은 파이썬 코드에서 실제 벤치마킹과 같은 작업을 수행한다. timeit.timeit 함수는 코드 조각이 필요하고, 100만 패스의 기본값으로 코드 조각이 여러 번 실행되며 필요한 총 시간을 가져온다. Timeit 모듈은 단일 작동 또는 함수 호출이 타이트 루프에서 어떻게 수행하는지 결정하는 데 가장 적합하다. 예를 들어 여러 번 반복된 작업에 대해 목록 포괄적인 리스트(List Comprehension) 또는 기존 리스트(conventional list) 중 어떤 것이 빠를지 결정할 때 사용할 수 있다. (일반적으로 포괄적인 리스트가 더 빠르다)

Time의 단점은 단순한 스톱워치 기능에 불과하며 주요 기능이 개별 라인이나 코드 블록에 마이크로 벤치마크로 사용된다는 것이다. 이 모듈은 코드를 단독으로 처리하는 경우에만 작동하며 전체 프로그램 분석에 충분하지 않다.

2. cProfile
cProfile은 파이썬 표준 라이브러리에서 제공하는 전체 프로그램 분석 프로파일이다. 실행할 때 cProfile는 프로그램의 모든 함수 호출을 추적하고 가장 자주 호출된 함수 및 평균 호출 소요 시간을 목록으로 생성한다.

cProfile는 표준 라이브러리에 포함돼 스톡 파이썬 설치에 사용할 수 있다는 장점이 있다. 또한 호출에 대한 여러 가지 통계를 제공한다. cProfile은 함수 호출 자체 명령에서 소요된 시간과 함수에 의해 호출된 다른 모든 호출에서 소요된 시간을 구분한다. 이를 통해 해당 함수가 느린지, 아니면 느린 다른 함수를 호출하는지 분별할 수 있다.

사용자는 cProfile는 자유롭게 만들 수 있는데, 전체 프로그램 실행을 샘플링하거나 선택한 기능이 실행될 때만 프로파일링을 할 수 있다. cProfile을 사용할 때에는 그 기능이 무엇을 하고 무엇을 호출하는지에 초점을 맞추는 것이 좋다. 이는 범위를 좁힌 후에만 잘 작동하지만, 전체 프로필을 추적하는 번거로움을 덜 수 있다.

단 cProfile은 기본적으로 많은 통계를 생성해 수많은 통계 중 필요한 정보를 찾기 어려워진다는 단점이 있다. 또한 cProfile의 실행모델은 모든 함수 호출을 트랩해 상당한 오버헤드를 생성한다. 따라서 cProfile은 운영 환경에서 실시간 데이터를 사용해 애플리케이션을 프로파일링하는 데 적합하지 않고, 개발 중에 애플리케이션을 프로파일링하는 데는 잘 동작한다.

3. Palanteer
Palanteer는 비교적 새로 추가된 것으로 파이썬과 C++ 프로그램을 프로파일링하는 데 사용할 수 있다. 따라서 C++ 라이브러리를 직접 작성하는 파이썬 응용프로그램을 작성할 때 앱의 두 구성 요소를 모두 세부적으로 파악하는 데 유용하다. Palanteer는 데스크톱에서 실행되는 GUI 앱에 결과를 표시하고 프로그램이 실행되면 실시간으로 업데이트된다.

Palanteer는 함수 호출, 예외, 가비지 수집 및 OS 수준 메모리 할당을 모두 추적한다. OS 수준과 메모리 할당은 앱의 성능 문제가 메모리 사용량 또는 개체 할당과 관련된 것일 경우 특히 유용하다.

Palanteer의 한 가지 단점은 전적으로 근원적으로 만들어야 한다는 것이다. 아직 설치 가능한 파이썬 휠로 컴파일된 바이너리를 사용할 수 없다. 따라서 C++ 컴파일러를 분리하고 CPython의 소스 복사본도 가지고 있어야 한다.

4. Pyinstrument
Pyinstrument는 프로그램을 추적하고 대부분의 시간을 차지하는 코드에 대한 보고서를 생성한다는 점에서 cProfile과 유사하다. 단 파이 계측기는 함수 호출의 모든 인스턴스를 후크하려고 시도하지 않는다. 프로그램의 호출 스택을 밀리초마다 샘플링해 눈에 덜 띄며, 대부분의 프로그램 런 타임에서 발생되는 문제를 감지할 수 있을 만큼은 민감하다.

Pyinstrument는 cProfile보다 더 간결한 보고서를 생성한다. 프로그램에서 가장 많은 시간이 걸리는 상위 기능을 표시해 가장 유력한 문제 원인을 분석하는 데 집중할 수 있다. 또한, 간단한 절차를 통해 신속하게 결과를 가질 수 있다.

Pyinstrument는 cProfile과 유사한 다양한 편의 기능이 있는데, 프로그램에서 프로파일러를 개체로 사용하고 전체 응용 프로그램 대신 선택한 기능의 동작을 기록할 수 있다. HTML을 포함해 다양한 방법으로 출력을 렌더링할 수 있으며 전체 호출 시간대도 확인할 수 있다.

Pyinstrument를 사용할 때 몇 가지 주의사항이 있는데, CPython을 사용해 만든 프로그램과 같이 C-컴파일 확장을 사용하는 일부 프로그램은 명령 줄로 호출할 때 제대로 작동하지 않을 수 있다. 그러나 프로그램 자체에서 Pyinstrument가 사용되는 경우 main() 함수를 Pyinstrument 호출로 래핑하는 방식으로 작동한다.

두 번째 주의사항은 Pyinstrument는 여러 쓰레드에서 실행되는 코드를 잘 처리하지 않는다는 것이다. 이 경우 아래의 Py-spy가 더 적합할 수 있다.

5. Py-spy
Py-spy는 Pyinstrument와 같이 모든 호출을 기록하려고 하는 대신, 프로그램 호출 스택의 상태를 정기적으로 샘플링하는 방식으로 작동한다. Py-spy는 러스트(Rust)로 작성된 핵심 컴포넌트(Pyinsturment는 C 확장자를 사용)를 가지며 프로파일링된 프로그램과 함께 구동되지 않으므로 프로덕선에서 실행 중인 코드와 함께 안전하게 사용할 수 있다.

이 아키텍처를 통해 Py-spy는 다른 많은 프로파일러들이 할 수 없는 일을 쉽게 처리한다. 프로 파일 멀티 쓰레딩 또는 하위 처리 파이썬 응용프로그램으로 사용된다. Py-spy는 C 확장자를 프로파일링할 수도 있지만, 이러한 확장자는 심볼을 사용해 컴파일해야 유용하다. 그리고 Cython으로 컴파일된 확장자의 경우 적절한 추적 정보를 수집하기 위해 생성된 C 파일이 필요하다.

앱을 검사할 때 Py-spy를 두 가지 방법으로 활용할 수 있다. 실행이 완료된 후 불꽃 그래프를 생성하는 Py-spy의 record 명령을 통해 앱을 실행할 수 있다. 또는 유닉스 톱 유틸리티와 동일한 방식으로 표현되는 파이썬 앱 내부의 라이브 업데이트 대화형 디스플레이를 불러오는 Py-spy top 명령을 사용할 수 있다. 또 명령 줄에서 개별 쓰레드 스택을 덤프할 수도 있다.

Py-spy에는 한 가지 단점이 있는데, 주로 프로그램 전체를 프로파일링하거나 일부 구성 요소를 외부에서 프로파일링하는 데 사용된다는 것이다. Py-spy는 특정 함수만 꾸미고 샘플링할 수 없다.

6. Yappi
Yappi(Yet Another Python Profiler)는 위에서 설명한 다른 프로파일러의 여러 가지 최고의 기능을 가지고 있으며, Yappi에서만 제공하는 일부 기능을 가지고 있다. PyCharm은 Yappi를 선택할 프로파일러 기본값으로 설치하므로 해당 IDE 사용자는 이미 Yappi에 대한 접근 권한을 가진다.

Yappi를 사용하기 위해선 프로파일링 메커니즘에 대한 보고서를 호출, 시작, 중지 및 생성하는 지침으로 코드를 작성한다. Yappi를 사용하면 소요 시간을 측정하기 위해 'wall time' 또는 'CPU time'을 선택할 수 있다. 전자는 스톱워치 기능에 해당하며, 후자는 시스템 네이티브 API를 통해 CPU가 실제로 코드를 작성하는 데 얼마나 시간이 걸렸는지, I/O 또는 스레드 절전 모드에 대한 일시 중지가 생략된 시간은 얼마인지를 표시한다. CPU 타임은 숫자 코드 실행과 같은 특정 작업에 실제로 소요되는 시간을 가장 정확하게 알려준다.

댓글 0

0 / 300
🙊 타인에게 불쾌감을 주는 욕설, 모욕적인 표현 등은 표기 불가로 텍스트로 지정되어 노출이 제한됩니다.
인기뉴스 더보기
댓글 작성
알림 문구가 한줄로 들어가는 영역입니다

신고하기

작성 아이디가 들어갑니다

내용 내용이 최대 두 줄로 노출됩니다

신고 사유를 선택하세요

이 이야기를
공유하세요

이 콘텐츠를 공유하세요.

콘텐츠 공유하고 수익 받는 방법이 궁금하다면👋>