파비의 매일매일 공부기록

파이썬 동시성 프로그래밍 - #6 디버깅과 벤치마킹 본문

Study/Python

파이썬 동시성 프로그래밍 - #6 디버깅과 벤치마킹

fabichoi 2021. 8. 13. 23:30

이번장은 디버깅과 벤치마킹에 대한 내용이다.

 

보통은 Pycharm으로 디버깅을 하기에 특별한 건 없어 보이나

사실 어떻게 디버깅이 되는지는 잘 몰라서 이번 기회에 배울 수 있으면 좋겠다.

 

그리고 벤치마킹은.. 무슨 의미일까? 아마 소요 시간 측정들을 의미할 것 같은데..

라는 의문을 갖고 책을 확인해 봤다.

 

저자는 프로그래밍이 단순 문제를 해결하고 끝내는 것이 아니고 보통은 솔루션을 유지하면서 산업이 이뤄지고 수입이 발생한다고 한다. 솔루션을 유지하는 것은 디버깅 및 요소를 추가하는 작업이므로 관련 툴을 익히는 게 중요하다고 한다.

 

테스트 전략 : 코드를 디버깅하는 가장 좋은 방법은 가능한 한 많은 코드를 다룰 수 있는 통합 테스트 구성하는 것.

- 테스트를 해야 하는 이유 : 버그를 고치는 소프트웨어 테스트는 매우 중요한 작업 중 하나. 실제로 빠른 수정이 가능. 

- 동시성 소프트웨어 시스템 테스트 : 멀티스레드 프로그램을 구현하기 전 모든 동시성 프로그램을 적절히 테스트해보는 것. 모든 소프트웨어 시스템은 최적화가 구현되기 전 정확도가 높아야 함.

- 어떤 것을 테스트할 것인가? : 저자가 종종 사용하는 방법은 코드 검사. 테스트할 코드가 몇 줄인 지 파악. 코드 검사에 집중하지 말고 코드의 가장 중요한 부분을 테스트하는데 집중할 것. 의도적으로 로직을 멈추게 해 보고 문제를 발생시켜볼 것.

- 단위 테스트 : 코드의 논리적 단일 단위를 테스트하는 프로그래밍적 검증. 일반적으로 단위란 코드에서 함수를 의미. PyUnit(JUnit을 파이썬으로 구현). 

- 동시성 코드의 단위 테스트 : 동시성 코드를 단위 테스트할 때 모든 문제를 해결할 수 있는 방법은 없음. 여러 가지 전략을 구성해 나아가고자 하는 방향으로 힘을 쏟아부어야 함. 멀티스레드라면 코드의 모든 시나리오 테스트 불가. '멀티스레드에서 동작하지 않는 코드의 단위 테스트' 및 '다양한 방법으로 멀티스레드 코드를 살피는 테스트를 작성' 하는 방법밖에 없음.

- 통합 테스트 : 코드 및 시스템의 여러 부분의 정확성을 확인하는 테스트. 기본적으로 단위 테스트보다 복잡. 시스템을 잘 이해할 수 있음. 동기화된 시스템을 실행하는데 도움을 줌.

 

디버깅 : 시스템이 복잡할수록 코드 내부의 버그는 급격히 증가. 특정 상황에서의 디버깅을 잘 알아야 개발 시간이 단축됨. 이 책에서는 단일 스레드에서의 예만 소개한다.

- 단일 스레드에서 : 단일 스레드 프로그램은 디버깅, 작동 및 논리적 오류를 잡는데 비결정적인 방식인 멀티스레드로 동작되는 시스템보다 쉬움.

- Pdb : Python Debugger. 기본 디버거. 완벽한 제어 및 런타임 도중 변숫값을 확인해 볼 수 있게 하며 단계적으로 코드를 실행하거나 중지점을 지정하는 등의 작업이 가능. Pdb를 사용해 프로그램 종료 디버깅을 할 수 있는데, 명령행을 통해 쌍방향 실행이 가능. 대화식 명령행을 사용해 코드를 실행하려면 l(리스트), n(다음), c(계속하기), s(단계), r(반환하기), b(중지하기) 등의 명령어의 숙지가 필요.

- 자식 스레드에서 예외 처리 : 멀티스레드 기반 앱을 작성할 때는 자식 스레드에서 온 예외를 어떻게 다룰지 고민해야 함. sys 모듈을 활용해 예외에 필요한 정보를 추출하고 스레드 세이프 큐에 넣는 방식 소개.

 

벤치마킹 : 작업이 얼마나 빨리 완료되는지 그 성능을 측정하는 것. 예를 들어 웹 크롤러라고 하면 일반적으로 초당 인덱싱 가능한 페이지 수를 측정하는 것을 벤치마킹이라고 함. 성능 최적화를 진행할 때 전체적인 프로그램의 현재 상태를 나타내는 벤치마킹을 시작하고 그 후 마이크로 벤치마킹의 조합을 이용하고 프로파일링으로 프로그램을 최적화하여 많은 양의 데이터를 처리한다.

- timeit 모듈 : 메인 앱의 작은 파이썬 코드 단위의 성능을 측정하도록 제공하는 모듈. 코드 상의 벤치마킹을 하고 반대로 명령행으로부터 호출해 원하는 시간의 코드 부분을 입력할 수 있는 등 유연한 모듈. time 모듈에 비해 더 정확한 시간을 측정하고자 개발됨. OS와 관련 없는 요인으로부터 영향을 덜 받아 정확한 측정을 가능하게 함.

- 데코레이터 활용 : 다소 지나친(?) 코드를 수동으로 삽입하거나 불필요한 코드 작성을 피해야 할 때 사용. 

- 타이밍 컨텍스트 관리자 : 콘텍스트 관리자는 with문을 실행할 때 나타나는 런타임 콘텍스트를 정의하는 객체. 파이썬에서 자체 Timer 콘텍스트 관리자 객체를 정의해 코드에 아무런 영향 없이 특정 부분의 시간을 측정할 때 사용 가능.

 

프로파일링 : 메모리를 얼마나 사용하는지 그리고 프로그램의 시간 복잡성 및 특정 작업의 사용과 같은 핵심 속성을 측정해야 함. 일반적으로 프로파일링은 동적 프로그램 분석이라고 불리는 기술로 측정을 시도. 실제 혹은 가상 프로세서 상에서 프로그램을 실행.

- cProfile : 파이썬에서 기본적으로 구성된 C 기반 모듈.

  > ncalls : 프로그램 실행에서 함수가 호출된 횟수

  > tottime : 특정 줄 및 함수가 실행되는데 걸린 전체 시간

  > percall : 전체 시간을 호출 횟수로 나눈 값

  > cumtime : 특정 줄 및 함수가 실행되는데 소비한 누적 시간

  > percall : cumtime을 호출 횟수로 나눈 값

  > filename:lineno(function) : 실제 측정하고자 하는 줄 및 함수

- line_profiler 툴 : 함수 내에 많은 코드가 있는 경우 기존의 방법으로 시간을 계산해 모든 줄을 감싸는 것이 거의 불가능. 이런 작업을 자동으로 하기 위해 코드상에서 부하가 높은 지점을 찾는 등 세세한 분석도 가능. 해당 모듈이 이런 작업을 프로그램 실행 시 한 줄씩 따라가며 진행. 모든 코드의 기본적인 소요 시간을 계산해 작업량을 줄여줌. 파이썬 내장 모듈은 아님. kernprof 툴(line_profiler에 기본적으로 포함)은 @profile 데코레이터를 사용해서 쉽게 분석 가능.

- 메모리 프로파일링 : 프로그램의 메모리 사용 프로파일은 중급 개발자가 효과적으로 시스템 문제를 디버깅하는데 꼭 필요한 기술 중 하나. plot 명령어로 그래프로 확인해 볼 수도 있다.

 

반응형
Comments