>  기사  >  백엔드 개발  >  Python 속도 향상

Python 속도 향상

高洛峰
高洛峰원래의
2016-10-19 13:25:121137검색

원래 웹 페이지의 성능을 더 잘 최적화하는 방법을 전혀 몰랐습니다. 그런데 최근 Python과 PHP로 유사한 웹 페이지의 렌더링 속도를 비교하던 중 우연히 한 번도 본 적이 없는 매우 간단하고 바보 같은 방법을 발견했습니다. 발견(직접 BS해야 했습니다): Discuz 포럼과 같은 일부 PHP 응용 프로그램과 마찬가지로 생성된 웹 페이지에 "이 페이지가 생성된 시간(초)"을 인쇄한 다음 테스트를 위해 웹 페이지를 계속 방문하면 다음을 수행할 수 있습니다. 작업으로 인해 병목 현상이 발생하는지, 병목 현상을 해결하는 방법을 알아보십시오.

그래서 SimpleCD가 홈페이지를 생성할 때 예상외로 0.2초 정도 소요되는 것을 발견했습니다. Discuz 포럼의 홈페이지 생성이 평균 0.02초밖에 걸리지 않는데, Discuz는 참을 수 없었습니다. 포럼의 홈페이지는 의심할 바 없이 SimpleCD의 홈페이지보다 훨씬 더 깁니다. 이 차이는 확실히 Python 언어와 Discuz 프로그램으로 인해 발생한 것이 아니기 때문에 당황스럽습니다. 최적화 잘됐어요.

첫 번째 중요한 것은 데이터 수를 가져오는 것입니다

SELECT count(*) FROM Verycd

이 작업은 매번 많은 시간이 걸립니다. 기본 키의 개수를 계산하기 위해 매번 데이터베이스를 잠그고 순회해야 하기 때문입니다. 데이터의 양이 많을수록 시간 소모가 커지며, N은 그 크기입니다. 사실 이 문제를 해결하는 방법은 매우 쉽습니다. 현재 데이터를 어디에든 저장하고, 데이터를 추가하거나 삭제할 때만 변경하므로 시간이 O(1)

두 번째로 큽니다. 하나는: 최신 20개의 업데이트된 데이터 목록을 가져오는 것입니다

SELECT Verycdid,title,brief,updtime FROM Verycd

ORDER BY updtime DESC LIMIT 20;

왜냐하면 updtime에 색인이 생성되어 있지만 실제로는 Query 시간이 색인을 검색하는 시간일 뿐입니다. 그런데 왜 이 작업이 느린 걸까요? 내 데이터는 게시 시간에 따라 삽입되기 때문에 업데이트 시간에 따라 표시되면 최소한 20개 이상의 다른 위치에서 I/O를 수행해야 하므로 속도가 느려집니다. 해결책은 한 곳에서 I/O를 수행하도록 하는 것입니다. 즉, 데이터베이스가 새 데이터를 추가하거나 원본 데이터를 변경하지 않는 한 이 문의 반환 결과는 캐시됩니다. 20배 더 빠릅니다.)

다음은 20개의 작은 사례입니다. 게시자 및 클릭 번호 정보 가져오기

SELECT owner FROM LOCK WHERE id=XXXX;

SELECT hit FROM stat WHERE id=XXXX;

문제를 해결하기 위해 여기에 SQL 조인 문이 없는 이유는 무엇입니까? 구조적 이유로 인해 이러한 데이터는 서로 다른 데이터베이스에 배치됩니다. Stat는 클릭률과 같은 데이터베이스이므로 자주 삽입해야 하기 때문에 mysql에 저장됩니다. mysql의 비극적인 인덱스 사용법 페이징 효율성으로 인해 sqlite3 데이터베이스에 저장되므로 조인할 수 없습니다. -.-

요컨대 지금의 해결 방법과 동일합니다. , 모두 캐시됨

제 예를 보면 웹 페이지 성능 최적화는 간단히 말해서 데이터베이스 쿼리를 캐싱하는 것으로 요약할 수 있습니다. 대부분의 웹 애플리케이션이 이렇다고 생각합니다.)

마지막으로 memcached의 차례입니다. 캐싱을 위해 파일을 사용한다면 여전히 디스크 I/ 아, 그렇다면 직접 메모리에 캐시하면 메모리 I/O가 훨씬 빨라질 것입니다. 이름에서 알 수 있듯이 memcached가 바로 그것입니다.

Memcached는 분산 공유 메모리 캐시를 지원할 수 있기 때문에 매우 강력한 도구입니다. 소규모 사이트의 경우 메모리 여유가 있는 경우에도 유용합니다. 홈페이지 메모리 버퍼의 크기는 10K를 넘지 않을 것으로 추정됩니다. 게다가 나도 메모리 재벌입니다.

구성 및 작동: 독립형 머신이고 구성할 것이 없으므로 메모리와 포트만 변경하면 됩니다.

vi /etc/memcached.conf

/etc/init.d /memcached restart

Python 웹 애플리케이션에 사용

memcache 가져오기

mc = memcache.Client(['127.0.0.1: 11211'], debug=0)

memcache는 실제로 맵 구조이며 가장 일반적으로 사용되는 두 가지 함수는 다음과 같습니다.

첫 번째 함수는 설정(키, 값, 시간 초과)입니다. , this 키를 값으로 매핑하는 것은 매우 간단합니다. Timeout은 매핑이 실패하는 경우를 나타냅니다

두 번째는 키가 가리키는 값을 반환하는 get(key) 함수입니다

일반적인 SQL 쿼리는 다음과 같이 수행할 수 있습니다

sql = 'verycd에서 count(*) 선택'

c = sqlite3.connect('verycd.db').cursor()



# 원본 처리방법

c.execute(sql)

count = c.fetchone()[0]



# 현재 처리방법

from hashlib import md5

key=md5(sql)

count = mc.get(key)

count가 아닌 경우:

c.execute(sql)

count = c.fetchone()[0]

mc.set(key,count,60*5) #5분간 저장

md5의 목적은 키 분배를 보다 균일하게 만드는 것입니다. 다른 코드는 매우 직관적이므로 설명하지 않겠습니다.


문 1과 문 2를 최적화한 후 홈페이지의 평균 생성 시간이 0.02초로 단축되었습니다. 이는 문 최적화 후와 동일한 크기입니다. 3, 마지막으로 memcached에서 몇 줄의 코드를 최적화한 결과 홈페이지 생성 시간이 약 0.006초로 단축되었으며, 성능이 3300% 향상되었습니다. 드디어 허리를 펴고 Discuz를 볼 수 있겠네요)


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.