파 이 썬 파충류 의 성능 에 대한 총화

9869 단어 Python파충성능
여기 서 우 리 는 웹 페이지 의 예 를 들 어 파충류 의 성능 을 한 걸음 한 걸음 이해 해 달라 고 요청 했다.
하나의 목록 이 url 을 저장 할 때 관련 데 이 터 를 가 져 와 야 합 니 다.우리 가 먼저 생각 하 는 것 은 순환 입 니 다.
단순 순환 직렬
이 방법 은 상대 적 으로 가장 느 린 것 이다.왜냐하면 하나의 순환 이 가장 오래 걸 리 고 모든 시간 을 합 친 것 이기 때문이다.
코드 는 다음 과 같 습 니 다:

import requests

url_list = [
  'http://www.baidu.com',
  'http://www.pythonsite.com',
  'http://www.cnblogs.com/'
]

for url in url_list:
  result = requests.get(url)
  print(result.text)
통과 스 레 드 탱크
스 레 드 탱크 의 방식 으로 접근 하면 전체적인 시간 은 모든 연결 에서 가장 오래 걸 리 는 것 이 고 순환 에 비해 많이 빨 라 집 니 다.

import requests
from concurrent.futures import ThreadPoolExecutor

def fetch_request(url):
  result = requests.get(url)
  print(result.text)

url_list = [
  'http://www.baidu.com',
  'http://www.bing.com',
  'http://www.cnblogs.com/'
]
pool = ThreadPoolExecutor(10)

for url in url_list:
  #           ,     fetch_request  
  pool.submit(fetch_request,url)

pool.shutdown(True)
스 레 드 탱크+리 셋 함수
리 셋 함수 callback 을 정의 합 니 다.

from concurrent.futures import ThreadPoolExecutor
import requests


def fetch_async(url):
  response = requests.get(url)

  return response


def callback(future):
  print(future.result().text)


url_list = [
  'http://www.baidu.com',
  'http://www.bing.com',
  'http://www.cnblogs.com/'
]

pool = ThreadPoolExecutor(5)

for url in url_list:
  v = pool.submit(fetch_async,url)
  #        
  v.add_done_callback(callback)

pool.shutdown()
프로 세 스 풀 통과 하기
프로 세 스 풀 방식 으로 접근 하 는 것 도 가장 오래 걸 리 는 것 에 달 려 있 습 니 다.그러나 스 레 드 에 비해 프로 세 스 는 더 많은 자원 을 소모 해 야 합 니 다.또한 url 에 접근 할 때 IO 작업 이기 때문에 프로 세 스 풀 보다 스 레 드 풀 이 더 좋 습 니 다.

import requests
from concurrent.futures import ProcessPoolExecutor

def fetch_request(url):
  result = requests.get(url)
  print(result.text)

url_list = [
  'http://www.baidu.com',
  'http://www.bing.com',
  'http://www.cnblogs.com/'
]
pool = ProcessPoolExecutor(10)

for url in url_list:
  #           ,       fetch_request  
  pool.submit(fetch_request,url)

pool.shutdown(True)
프로 세 스 풀+리 셋 함수
이러한 방식 은 스 레 드+리 셋 함수 의 효과 와 같 으 며,상대 적 으로 스 레 드 를 여 는 것 보다 자원 을 낭비 합 니 다.

from concurrent.futures import ProcessPoolExecutor
import requests


def fetch_async(url):
  response = requests.get(url)

  return response


def callback(future):
  print(future.result().text)


url_list = [
  'http://www.baidu.com',
  'http://www.bing.com',
  'http://www.cnblogs.com/'
]

pool = ProcessPoolExecutor(5)

for url in url_list:
  v = pool.submit(fetch_async, url)
  #         
  v.add_done_callback(callback)

pool.shutdown()
주류 의 단일 라인 이 병발 하 는 몇 가지 방식 을 실현 하 다
  • asyncio
  • gevent
  • Twisted
  • Tornado
  • 다음은 이 네 가지 코드 의 실현 예 이다.
    asyncio 예 1:
    
    import asyncio
    
    
    @asyncio.coroutine #         
    def func1():
      print('before...func1......')
      #      yield from,       asyncio.sleep   time.sleep
      yield from asyncio.sleep(2)
      print('end...func1......')
    
    
    tasks = [func1(), func1()]
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(*tasks))
    loop.close()
    위의 효 과 는 before 두 개의 내용 을 동시에 인쇄 한 후 2 초 동안 end 내용 을 인쇄 하 는 것 입 니 다.
    여기 asyncio 는 http 요청 을 보 내 는 방법 을 제공 하지 않 았 지만,yield from 에서 http 요청 을 구성 할 수 있 습 니 다.
    asyncio 예 2:
    
    import asyncio
    
    
    @asyncio.coroutine
    def fetch_async(host, url='/'):
      print("----",host, url)
      reader, writer = yield from asyncio.open_connection(host, 80)
    
      #       
      request_header_content = """GET %s HTTP/1.0\r
    Host: %s\r
    \r
    """ % (url, host,) request_header_content = bytes(request_header_content, encoding='utf-8') # writer.write(request_header_content) yield from writer.drain() text = yield from reader.read() print(host, url, text) writer.close() tasks = [ fetch_async('www.cnblogs.com', '/zhaof/'), fetch_async('dig.chouti.com', '/pic/show?nid=4073644713430508&lid=10273091') ] loop = asyncio.get_event_loop() results = loop.run_until_complete(asyncio.gather(*tasks)) loop.close()
    asyncio+aiohttp 코드 예:
    
    import aiohttp
    import asyncio
    
    
    @asyncio.coroutine
    def fetch_async(url):
      print(url)
      response = yield from aiohttp.request('GET', url)
      print(url, response)
      response.close()
    
    
    tasks = [fetch_async('http://baidu.com/'), fetch_async('http://www.chouti.com/')]
    
    event_loop = asyncio.get_event_loop()
    results = event_loop.run_until_complete(asyncio.gather(*tasks))
    event_loop.close()
    asyncio+requests 코드 예
    
    import asyncio
    import requests
    
    
    @asyncio.coroutine
    def fetch_async(func, *args):
      loop = asyncio.get_event_loop()
      future = loop.run_in_executor(None, func, *args)
      response = yield from future
      print(response.url, response.content)
    
    
    tasks = [
      fetch_async(requests.get, 'http://www.cnblogs.com/wupeiqi/'),
      fetch_async(requests.get, 'http://dig.chouti.com/pic/show?nid=4073644713430508&lid=10273091')
    ]
    
    loop = asyncio.get_event_loop()
    results = loop.run_until_complete(asyncio.gather(*tasks))
    loop.close()
    gevent+requests 코드 예
    
    import gevent
    
    import requests
    from gevent import monkey
    
    monkey.patch_all()
    
    
    def fetch_async(method, url, req_kwargs):
      print(method, url, req_kwargs)
      response = requests.request(method=method, url=url, **req_kwargs)
      print(response.url, response.content)
    
    # #####      #####
    gevent.joinall([
      gevent.spawn(fetch_async, method='get', url='https://www.python.org/', req_kwargs={}),
      gevent.spawn(fetch_async, method='get', url='https://www.yahoo.com/', req_kwargs={}),
      gevent.spawn(fetch_async, method='get', url='https://github.com/', req_kwargs={}),
    ])
    
    # #####     (           ) #####
    # from gevent.pool import Pool
    # pool = Pool(None)
    # gevent.joinall([
    #   pool.spawn(fetch_async, method='get', url='https://www.python.org/', req_kwargs={}),
    #   pool.spawn(fetch_async, method='get', url='https://www.yahoo.com/', req_kwargs={}),
    #   pool.spawn(fetch_async, method='get', url='https://www.github.com/', req_kwargs={}),
    # ])
    grequests 코드 예
    이 건 requests+gevent 를 패키지 로 했 습 니 다.
    
    import grequests
    
    
    request_list = [
      grequests.get('http://httpbin.org/delay/1', timeout=0.001),
      grequests.get('http://fakedomain/'),
      grequests.get('http://httpbin.org/status/500')
    ]
    
    
    # #####           #####
    # response_list = grequests.map(request_list)
    # print(response_list)
    
    
    # #####          (    ) #####
    # def exception_handler(request, exception):
    # print(request,exception)
    #   print("Request failed")
    
    # response_list = grequests.map(request_list, exception_handler=exception_handler)
    # print(response_list)
    twisted 코드 예
    
    #getPage   requets  ,defer      ,rector      
    from twisted.web.client import getPage, defer
    from twisted.internet import reactor
    
    def all_done(arg):
      reactor.stop()
    
    def callback(contents):
      print(contents)
    
    deferred_list = []
    
    url_list = ['http://www.bing.com', 'http://www.baidu.com', ]
    for url in url_list:
      deferred = getPage(bytes(url, encoding='utf8'))
      deferred.addCallback(callback)
      deferred_list.append(deferred)
    #           ,             
    dlist = defer.DeferredList(deferred_list)
    dlist.addBoth(all_done)
    
    reactor.run()
    tornado 코드 예
    
    from tornado.httpclient import AsyncHTTPClient
    from tornado.httpclient import HTTPRequest
    from tornado import ioloop
    
    
    def handle_response(response):
      """
             (       ,   IO  ),   ioloop.IOLoop.current().stop()
      :param response: 
      :return: 
      """
      if response.error:
        print("Error:", response.error)
      else:
        print(response.body)
    
    
    def func():
      url_list = [
        'http://www.baidu.com',
        'http://www.bing.com',
      ]
      for url in url_list:
        print(url)
        http_client = AsyncHTTPClient()
        http_client.fetch(HTTPRequest(url), handle_response)
    
    
    ioloop.IOLoop.current().add_callback(func)
    ioloop.IOLoop.current().start()
    이상 은 파 이 썬 파충류 의 성능 에 관 한 상세 한 내용 입 니 다.파 이 썬 파충류 의 성능 에 관 한 자 료 는 다른 관련 글 에 주목 하 세 요!

    좋은 웹페이지 즐겨찾기