> 백엔드 개발 > 파이썬 튜토리얼 > Python 고성능 프로그래밍 방법 1

Python 고성능 프로그래밍 방법 1

高洛峰
풀어 주다: 2016-10-18 10:48:23
원래의
1137명이 탐색했습니다.

Zen of Python을 읽고 이것을 Python 파서에 입력하세요. 예민한 Python 초보자는 "parse"라는 단어를 보고 Python이 "느려야 합니다!"라고 생각할 수도 있습니다. Python 프로그램이 컴파일된 언어만큼 효율적이고 빠르지 않다는 것은 의심의 여지가 없습니다. Python이 이러한 분야에 적합하지 않다고 말할 것입니다. 그러나 YouTube는 Python을 사용하여 시간당 4천만 건의 비디오 요청을 처리했습니다. 효율적인 코드를 작성하고 필요할 때 외부 구현(C/C++) 코드를 사용하면 됩니다. 다음은 더 나은 Python 개발자가 되는 데 도움이 되는 몇 가지 팁입니다.

1. 내장 함수를 사용할 수 있습니다. Python에서 효율적인 코드를 작성하지만 내장 함수를 이기기가 어렵습니다. 검증된 대로 매우 빠릅니다. 2. 문자열을 연결하려면 "+"를 사용할 수 있습니다. Python은 변경할 수 없으며 각 "+" 작업은 새 문자열을 생성하고 이전 내용을 복사합니다. 일반적인 사용법은 Python의 배열 모듈을 사용하여 완료되면 Join() 함수를 사용하여 최종 문자열을 만드는 것입니다. >

>>> #input()의 청크에 대해 많은 수의 문자열

>>>을 붙이는 데 좋습니다:

>>> my_string.join(chunk)

3. Python 다중 할당을 사용하여 변수 교환

Python에서는 우아하고 빠릅니다.

>>> x, y = y, x

매우 느립니다.

>>> temp = x

>>> x = y

>>> y = temp

4. 지역 변수를 사용하려면

Python은 전역 변수를 검색하는 것보다 지역 변수를 더 빠르게 검색합니다. 즉, "전역" 키워드를 사용하지 마세요.

5. "in"을 사용해 보세요

간단하고 빠른 "in" 키워드를 사용하세요.

>>> 키 순서:

>>> “found” 인쇄

6. 속도 향상

"import" 선언을 함수로 이동하고 필요할 때만 가져옵니다. 즉, 일부 모듈이 즉시 필요하지 않은 경우 나중에 가져올 필요가 없습니다. 시작 시 모듈 수가 많으면 프로그램 시작 속도가 빨라집니다. 이 기술은 전체 성능을 향상시킬 수는 없지만 모듈 로딩 시간을 보다 균등하게 할당하는 데 도움이 됩니다.

7. 무한 루프에는 "while 1"을 사용하세요. 🎜 >

때때로 프로그램에서 무한 루프가 필요할 수 있습니다(예: 청취 소켓의 인스턴스). "while true"는 동일한 작업을 수행할 수 있지만 "while 1"은 단일 단계 작업일 수 있습니다. Python 성능을 향상시키세요.

>>> while 1:

>>> # 작업을 더 빠르게 while 1

>>> while True:

>>> # 작업 수행, wile True

8. 목록 이해 사용

Python 2.0부터 목록 이해를 사용하여 많은 "for" 및 "를 대체할 수 있습니다. while" 블록. 목록 이해를 사용하는 것이 일반적으로 더 빠르며 Python 파서는 루프에서 예측 가능한 패턴을 찾아 최적화할 수 있습니다. 추가 이점은 목록 이해가 더 읽기 쉽고(함수형 프로그래밍) 대부분의 경우 더 잘 작동한다는 것입니다. , 추가 카운트 변수를 저장합니다. 예를 들어, 1과 10 사이의 짝수를 세어 보겠습니다.

>>> # 범위를 반복하는 좋은 방법

>>> evens = [ i for i in range( 10) if i%2 == 0]

>>> [0, 2, 4, 6, 8]

>>> # 다음은 그다지 파이썬적이지 않습니다

>>> i = 0

>>> evens = []

>>> while i

>>> if i %2 == 0: evens.append(i)

>>> i += 1

>>> [0, 2, 4, 6, 8]

9를 사용하세요. )는 긴 시퀀스를 처리합니다.

xrange()는 시퀀스에서 호출당 하나의 정수 요소만 생성하므로 시스템 메모리를 많이 절약할 수 있습니다. 대조적으로, range()는 전체 요소 목록을 직접 제공하므로 루핑에 사용될 때 불필요한 오버헤드가 발생합니다.

10. Python 생성기 사용:

메모리를 절약하고 성능을 향상시킬 수도 있습니다. 예를 들어 비디오 스트림의 경우 전체 스트림 대신 바이트 단위로 보낼 수 있습니다. 예를 들어

>>> 덩어리 = ( 1000 * i for i in xrange(1000))

>>> 덩어리

>>> 덩어리.다음()

0

>>> 덩어리.다음()

1000

>>> 덩어리.다음( )

2000

11. itertools 모듈 이해:

이 모듈은 반복 및 조합에 매우 효과적입니다. 단 세 줄의 Python 코드로 목록 [1, 2, 3]의 모든 순열을 생성해 보겠습니다.

>>> import itertools

>>> iter = itertools.permutations( [ 1,2,3])

>>> 목록(반복)

[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), ( 3, 1, 2), (3, 2, 1)]

12. 목록을 정렬된 상태로 유지하는 bisect 모듈을 알아보세요.

이것은 무료 이진 검색 구현 및 빠른 삽입입니다. 주문된 시퀀스 도구. 즉, 다음을 사용할 수 있습니다.

>>> import bisect

>>> bisect.insort(list, element)

목록에 요소를 삽입했습니다. 그리고 컨테이너 정렬을 유지하기 위해 sort()를 다시 호출할 필요가 없습니다. 긴 시퀀스에서는 비용이 많이 들 수 있기 때문입니다.

13. Python 목록은 실제로 배열이라는 점을 이해하세요.

Python의 리스트 구현은 사람들이 일반적으로 이야기하는 컴퓨터 과학의 일반적인 단일 연결 리스트로 구현되지 않습니다. Python의 목록은 배열입니다. 즉, 처음부터 검색할 필요 없이 일정한 시간 O(1)에 목록의 요소를 검색할 수 있습니다. 요점은 무엇입니까? Python 개발자는 목록 개체 insert()를 사용할 때 두 번 생각해야 합니다. 예: >>> list.insert(0, item)

목록 앞에 요소를 삽입하는 것은 모든 후속 요소 때문에 효율적이지 않습니다. 목록에서 아래 첨자를 변경해야 합니다. 그러나 목록 끝에 요소를 효과적으로 추가하려면 deque를 먼저 사용하세요. Python의 deque는 이중 연결 목록으로 구현되므로 빠릅니다. 더 이상 말하지 마세요.

14. dict 및 set을 사용하여 멤버 테스트: dict 또는 set에 요소가 있는지 확인합니다. 이는 Python에서 매우 빠릅니다. 이는 dict와 set이 해시 테이블을 사용하여 구현되기 때문입니다. 검색 효율성은 O(1)에 도달할 수 있습니다. 따라서 멤버를 자주 확인해야 하는 경우 set 또는 dict를 컨테이너로 사용하세요.

>>> mylist = ['a', 'b', 'c'] #Slower, list로 멤버쉽을 확인하세요.

>>> mylist의 'c'

>>> True

>>> myset = set(['a', 'b', 'c' ] ) # 더 빠르게, set:

>>> 'c' in myset:

>>> True

Schwartzian Transform을 사용하는 Sort():

기본 list.sort() 함수는 매우 빠릅니다. Python은 목록을 자연 순서로 정렬합니다. 때로는 비자연적인 순서로 정렬해야 하는 경우도 있습니다. 예를 들어 서버 위치를 기준으로 IP 주소를 정렬하려고 합니다. Python은 사용자 정의 비교를 지원합니다. list.sort(CMP())를 사용할 수 있습니다. 이는 함수 호출의 추가 오버헤드로 인해 list.sort()보다 느립니다. 성능이 문제라면 Schwartzian Transform을 기반으로 Guttman-Rosler Transform을 적용할 수 있습니다. 이는 실제로 사용되는 알고리즘에만 관심이 있으며, 간단한 작동 원리는 목록을 변환하고 Python의 내장 함수를 호출할 수 있다는 것입니다. list.sort()에서 -> list.sort(CMP())를 사용하지 않고 더 빠르게 -> 더 느리게.

16. Python 데코레이터 캐시 결과:

"@" 기호는 Python의 데코레이션 구문입니다. 이는 단지 추적, 잠금 또는 로깅만을 위한 것이 아닙니다. 이후 사용을 위해 호출 결과를 기억하도록 Python 함수를 장식할 수 있습니다. 이 기술을 메모이제이션이라고 합니다. 예는 다음과 같습니다.

>>> from functools import Wraps

>>> def memo(f):

>>> 캐시 = { }

>>> @wraps(f)

>>> def Wrap(*arg):

>>> arg가 캐시에 없는 경우: 캐시['arg'] = f( *arg)

>>> return 캐시['arg']

>>> return Wrap

피보나치 함수에 데코레이터를 사용할 수도 있습니다.

>>> @memo

>>> def fib(i):

>>> if i

>>> return fib( i-1) + fib(i-2)

여기서 핵심 아이디어는 다음과 같습니다. 계산된 각 피보나치 값이 캐시에 있는 경우 이를 기억하도록 함수(장식) 기능을 강화합니다. 더 이상 계산할 필요가 없습니다.

17. Python의 GIL(전역 해석기 잠금) 이해:

CPython의 메모리 관리는 스레드로부터 안전하지 않기 때문에 GIL이 필요합니다. 단순히 여러 스레드를 생성하면서 Python이 멀티 코어 시스템에서 더 빠르게 실행되기를 바랄 수는 없습니다. 이는 GIL이 여러 네이티브 스레드가 동시에 Python 바이트코드를 실행하는 것을 방지하기 때문입니다. 즉, GIL은 모든 스레드를 직렬화합니다. 그러나 스레드를 사용하면 생성된 여러 프로세스를 관리하여 Python 코드와 독립적으로 실행되는 프로그램의 속도를 높일 수 있습니다.

18. 문서만큼 Python 소스 코드에 익숙해지세요.

일부 Python 모듈은 성능을 위해 C로 구현됩니다. 성능이 중요하고 공식 문서가 충분하지 않은 경우 자유롭게 소스 코드를 탐색해 보세요. 기본 데이터 구조와 알고리즘을 찾을 수 있습니다. Python의 소스 코드 라이브러리는 훌륭한 장소입니다: http://svn.python.org/view/python/trunk/Modules

결론:

이것은 두뇌 사고를 대체할 수 없습니다. 이 문서의 Python 제안은 좋은 성능을 얻는 데 도움이 될 수 있도록 내부를 열고 완전히 이해하는 것입니다. 속도가 충분하지 않으면 Python 외부 도움이 필요합니다. 외부 코드를 분석하고 실행하는 방법은 이 기사의 두 번째 부분에서 다루겠습니다.

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿