메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일 >

[진지한 파이써니스타 인터뷰] 빅터 스티너와 파이썬 코드 최적화에 대해

한빛미디어

|

2021-03-05

|

by 에릭 윈드밀

11,447

 
파이썬 작동 원리에서 확장, 테스트, 배포, 최적화까지
『진지한 파이썬』 중
 

빅터 스티너Victor Stinner는 오랫동안 파이썬 해커이자 핵심 기여자로 파이썬의 많은 모듈을 개발했습니다. 2013년 PEP 454를 작성했고 파이썬에서 메모리 블록 할당을 추적하기 위한 새로운 tracemalloc 모듈을 제안했으며, FAT라는 간단한 AST 최적화 프로그램을 작성했습니다. 또한 CPython 성능 향상에도 정기적으로 기여합니다.
· · ·
Q. 파이썬 코드를 최적화하기 위한 좋은 출발 전략은 무엇입니까?
파이썬뿐 아니라 다른 언어에서도 같습니다. 우선, 안정적이고 재현 가능한 벤치마크 결과를 얻으려면 잘 정의한 사례가 필요합니다. 신뢰할 수 있는 벤치마크 없이 다른 최적화를 시도하면 시간이 낭비되고 섣부른 최적화가 될 수 있습니다. 쓸모없는 최적화는 소스 코드를 더 나쁘게 하거나 읽을 수 없거나 느리게 만들 수 있습니다. 가치가 있다면 유용한 최적화를 통해 프로그램 속도를 5% 이상 높여야 합니다.
소스 코드의 특정 부분이 느린 것으로 확인되면 이 소스 코드에 대한 벤치마크를 준비해야 합니다. 짧은 기능에 대한 벤치마크를 일반적으로 마이크로 벤치마크micro-benchmark라고 합니다. 마이크로 벤치마크의 최적화를 하려면 속도가 최소 20%에서 25% 향상되어야 합니다.
다른 컴퓨터, 다른 운영체제 또는 다른 컴파일러에서 벤치마크를 실행하는 것은 흥미로울 수 있습니다. 예를 들어 realloc()의 성능은 리눅스와 윈도우에서 다를 수 있습니다.
Q. 파이썬 코드를 프로파일링하거나 최적화하기 위해 쓰면 좋은 도구는 무엇입니까?
파이썬 3.3에는 벤치마크의 경과 시간을 측정하는 time.perf_counter() 함수가 있습니다. 이는 가능한 한 최상으로 결과를 제공합니다.
테스트는 두 번 이상 실행해야 합니다. 최소 3번에서 최대 5번이면 충분합니다. 테스트를 반복하면 디스크 캐시와 CPU 캐시가 채워집니다. 저는 최소의 타이밍을 유지하는 것을 선호하지만 다른 개발자는 기하 평균을 선호합니다.
마이크로 벤치마크의 timeit 모듈은 사용하기 쉽고 결과를 빠르게 제공하지만 기본 매개변수를 사용하기 때문에 결과를 신뢰할 수 없습니다. 안정적인 결과를 얻으려면 테스트를 수동으로 반복해야 합니다.
최적화에는 많은 시간이 소요될 수 있으므로 CPU를 가장 많이 사용하는 함수에 집중하는 것 이 좋습니다. 이러한 함수를 찾기 위해 파이썬에는 cProfile 및 profile 모듈이 있어 각 함수에 소요된 시간을 기록합니다.
Q. 성능을 향상시킬 수 있는 파이썬 팁이 있습니까?
표준 라이브러리를 가능한 한 많이 재사용해야 합니다. 테스트가 잘되어 있고 대체로 효율적입니다. 파이썬 기본 자료형은 C로 구현되며 성능이 좋습니다. 최상의 성능을 얻으려면 올바른 자료형을 사용하세요. 파이썬은 dict, list, deque, set 등 다양한 종류의 자료구조를 제공합니다.
파이썬을 최적화하는 데 몇 가지 팁이 있지만, 약간의 속도 향상을 위해 소스 코드를 읽기 어렵게 만들기 때문에 피하는 게 좋습니다.
파이썬의 선(PEP 20)은 ‘한 가지 분명한 방법이 있어야 한다’라고 합니다. 실제로 파이썬 코드를 작성하는 방법에는 여러 가지가 있고 성능은 같지 않습니다. 사례에 맞는 벤치마크만 신뢰하세요.
Q. 파이썬의 어느 영역이 가장 열악하고 주의해야 합니까?
일반적으로 새 애플리케이션을 개발하는 동안 성능은 걱정하지 않습니다. 섣부른 최적화는 모든 악의 근원입니다. 느린 함수를 식별했을 때는 알고리즘을 변경합니다. 알고리즘과 컨테이너 유형을 잘 선택하면 C에서 짧은 함수를 다시 작성하여 최상의 성능을 얻을 수 있습니다.
CPython의 한 병목현상은 GIL입니다. 두 개의 스레드는 동시에 파이썬 바이트코드를 실행할 수 없습니다. 그러나 이러한 제한 사항은 두 개의 스레드가 순수한 파이썬 코드를 실행할 때만 중요합니다. 대부분의 처리 시간이 함수 호출에 소비되고 이러한 함수가 GIL을 해제하면, GIL은 병목현상이 아닙니다. 예를 들어 대부분의 입출력 기능은 GIL을 해제합니다.
멀티프로세싱 모듈을 사용하여 GIL 문제를 쉽게 해결할 수 있습니다. 구현하기가 더 복잡한 또 다른 옵션은 비동기 코드를 작성하는 것입니다. 네트워크 지향 라이브러리인 트위스티드, 토네이도, 튤립Tulip 프로젝트는 이 기술을 사용합니다.
Q. 파이썬의 어느 영역이 가장 열악하고 주의해야 합니까?
파이썬을 잘 이해하지 못하면 비효율적인 코드를 작성할 수 있습니다. 예를 들어 복사가 필요하지 않을 때 copy.deepcopy()가 잘못 사용된 것을 본 적이 있습니다.
또 다른 성능 저하 요인은 비효율적인 자료구조입니다. 항목이 100개 미만인 컨테이너 유형은 성능에 영향을 미치지 않습니다. 항목이 많을수록 각 작업의 복잡성(add, get, delete)과 그 영향을 알아야 합니다.
· · ·
댓글 입력
자료실