Perflint 사용하는 방법 — Python용 성능 린터
초기에 성능 문제를 감지하고 도중에 더 나은 성능의 코드를 작성하는 방법을 배우십시오.
현대의 소프트웨어 개발에서 성능은 테스트 노력뿐만 아니라 자체 개발 프로세스에서도 가장 우선시됩니다.
이 기사에서는 성능 린팅을 Python 애플리케이션 개발에 쉽게 통합하고 더 나은 코드를 만드는 방법을 보여줍니다.
성능 엔지니어링은 성능 고려 사항이 사전에 고려되는 소프트웨어 엔지니어링의 성장하는 분야입니다.
성능에 대한 보다 직관적인 접근 방식은 프로젝트가 종료되는 동안 성능 테스트를 실행하고 모든 기능 요구 사항이 충족된 후 이 성능을 충족하도록 하는 것입니다.
그러나 이 접근 방식은 비효율적이고 비용이 많이 드는 것으로 보입니다.
Empirical Software Engineering Journal에 발표된 최근의 민족지학적 연구는 성능 보증의 일반적인 관행을 탐구하는 것을 목표로 했습니다.
연구원은 여러 기술 전문가를 6개월 동안 지속적으로 인터뷰한 결과 다음과 같은 결론을 내렸습니다.
이 연구는 사례 조직이 성능 보증을 위해 여전히 폭포수 접근 방식에 의존하고 있음을 보여줍니다. 이러한 접근 방식은 ASD에 부적합한 것으로 나타났습니다.[Agile Software Development], 따라서 성과 평가 활동의 차선책 관리로 이어집니다. 우리는 성과 보증 프로세스를 개선할 때 세 가지 주요 과제를 요약했습니다. (i) 성과 평가 활동 관리, (ii) 지속적인 성과 평가 및 (iii) 성과 평가 노력 정의.
이는 소프트웨어 개발의 수명 주기에서 성능 보증이 우선시되고 폭포수 접근 방식 대신 애자일 방법론을 고수하는 것이 중요함을 보여줍니다.
진짜 문제는 프로그래머가 잘못된 장소와 잘못된 시간에 효율성을 걱정하는 데 너무 많은 시간을 보냈다는 것입니다. 조기 최적화는 프로그래밍에서 모든 악(또는 적어도 대부분)의 근원입니다.
이 인용문은 1974년 Turing 상을 수상한 Donald Knuth가 쓴 1968년 책 'The Art of Computer Programming'에서 발췌한 것입니다.
Knuth는 프로그래머가 성능에 대해 직관적으로 생각하는 경향이 있다고 주장했습니다(이 인용문은 60년이 넘었습니다...).
그들은 일반적으로 이해하기 어려운 코드 부분이 기계가 실행하는 데 가장 많은 시간이 소요되는 코드 부분이라고 가정합니다.
그리고 전반적으로 그의 진술은 프로그래머가 프로파일링 없이 코드를 맹목적으로 최적화하지 않도록 경고하기 위한 것이었습니다.
많은 프로그래머들은 그의 진술을 맥락에서 벗어나 마치 프로그램을 최적화하기 위한 노력이 애플리케이션 개발의 마지막 단계에서 이루어져야 하는 것처럼 해석하며 이 주장은 단지 거짓입니다.
성능 최적화는 소프트웨어 설계 및 구현의 일부이며 다른 모든 소프트웨어 개발 노력과 마찬가지로 위험 대 이점 측면에서 우선 순위가 되어야 합니다.
나는 일반적으로 린터에 대해 이야기했고 pylint
이전 기사에서.
성능 린터는 코드에서 성능 안티 패턴을 감지하는 것을 목표로 하는 보다 구체적인 린터입니다.
이전 글에서 보여드린 것처럼, pylint
플러그인으로 매우 쉽게 확장하여 더 많은 검사기 기능을 추가할 수 있습니다.
그래서 멋진 파이썬 개발자이자 저자인 Anthony Shaw는 확장할 플러그인을 개발해 왔습니다. pylint
성능 문제를 감지합니다.
이 린터를 사용하여 python 개발자는 응용 프로그램 성능을 향상하고 python 내부 및 성능에 미치는 영향에 대해 배울 수 있습니다.
그다지 유용하지 않은 코드를 살펴보겠습니다.
따라서 전역 변수가 2로 설정되어 있습니다. main
기능과 main
절.
주 함수에는 정수 변수의 로컬 목록이 있으며 목록을 반복하고 전역 변수에 의해 구동되는 각 숫자를 인쇄합니다.
코드를 실행해 보겠습니다.
python example.py
산출:
1
4
9
16
이제 이 코드를 린트할 수 있습니다. 먼저 다음을 설치해야 합니다. pylint
핍 사용:
pip install pylint
이제 실행하자 pylint
:
pylint example.py
결과는 다음과 같습니다.
--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)
오류가 발견되지 않았고 내 코드는 10/10을 기록했습니다.
이제 추가하자 perflint
파티에 :)
pip install perflint
이제 우리는 실행할 수 있습니다 pylint
그리고 사용 perflint
플러그인으로!
pylint --load-plugins perflint example.py
결과:
************* Module __main__
myapp\__main__.py:8:27: W8202: Lookups of global names within a loop is inefficient, copy to a local variable outside of the loop first. (loop-invariant-global-usage)
myapp\__main__.py:6:16: W8301: Use tuple instead of list for a non-mutated sequence (use-tuple-over-list)------------------------------------------------------------------
Your code has been rated at 7.14/10 (previous run: 5.00/10, +2.14)
Perflint는 2개의 문제를 발견했고 내 코드 점수는 7.14로 떨어졌습니다!
다음 두 가지 문제를 살펴보겠습니다.
문제 1 — 루프 내 전역 이름 조회
루프에 초점을 맞추고 목록을 반복한 다음 전역 변수를 사용합니다.
전역 변수를 조회하려면 파이썬 인터프리터가 이름과 색인의 전체 영역에 대해 조회를 수행해야 합니다. STORE_NAME
opcall
파이썬 바이트코드 인터프리터
그러나 함수를 정의할 때 고정된 수의 지역 변수를 가지므로 파이썬이 고정된 배열을 설정하고 지역 변수 이름과 관련된 값을 쉽게 찾을 수 있습니다. STORE_FAST
파이썬 바이트코드 인터프리터의 opcall.
따라서 이에 대한 빠른 수정은 전역 변수를 지역 변수에 저장한 다음 루프 내에서 해당 지역 변수를 사용할 수 있습니다.
이제 하자 perflint
다시:
pylint --load-plugins perflint example.py
결과:
************* Module __main__
myapp\__main__.py:6:16: W8301: Use tuple instead of list for a non-mutated sequence (use-tuple-over-list)------------------------------------------------------------------
Your code has been rated at 8.75/10 (previous run: 7.14/10, +1.61)
좋습니다. 첫 번째 문제가 해결되었습니다.
이제 두 번째 문제를 해결해 보겠습니다.
문제 2 - 목록 대신 튜플 사용
우리 코드의 목록 변수는 절대 변경되지 않으므로 이 경우 변경할 수 없는 개체를 사용하는 것이 좋습니다.
여기서 선호하는 불변 객체는 튜플입니다.
이 문제를 해결해 보겠습니다.
그리고 지금 perflint
:
pylint --load-plugins perflint example.py
결과:
-------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 8.75/10, +1.25)
만점!
코드의 빠른 예와 느린 예를 비교해 보겠습니다.
사용 timeit
'빠른' 버전이 실제로 얼마나 더 빠른지 평가할 수 있습니다.
달리다:
python example.py
결과:
fast_main execution time = 7.155288799898699 sec
slow_main execution time = 7.3095553000457585 sec
'빠른' 버전의 경우 7.15초 대 '느린' 버전의 경우 7.31초로 상당히 눈에 띕니다.
읽어 주셔서 감사합니다.
'Coding' 카테고리의 다른 글
Parcel을 사용하여 Phaser 3 게임 묶는 방법 (0) | 2022.04.13 |
---|---|
프로덕션 전 대량 테스트 API - Azure Durable Functions가 포함된 Azure DevOps 릴리스 게이트하는 방법 (0) | 2022.04.12 |
Doppler를 사용하여 AWS 암호 관리 (0) | 2022.04.10 |
Flutter와 Node.js로 실시간 채팅 앱을 만드는 방법 (0) | 2022.04.09 |
Lambda 대 Step Functions: 비용과 성능의 싸움 (0) | 2022.04.08 |
댓글