ASYNCIO HTTP请求慢?

问题描述 投票:7回答:3

我使用ASYNCIO和要求基准一系列HTTP请求。

出于某种原因,它的速度稍慢使用ASYNCIO不仅仅是直请求。任何想法,为什么?我使用不当ASYNCIO?

import asyncio
import functools
import requests
import time

ts = time.time()
for i in range(10):
  @asyncio.coroutine
  def do_checks():
      loop = asyncio.get_event_loop()
      req = loop.run_in_executor(None, functools.partial(requests.get, "http://google.com", timeout=3))
      resp = yield from req
      print(resp.status_code)

  loop = asyncio.get_event_loop()
  loop.run_until_complete(do_checks())
te = time.time()
print("Version A: " + str(te - ts))

ts = time.time()
for i in range(10):
  r = requests.get("http://google.com", timeout=3)
  print(r.status_code)
te = time.time()

print("Version B:  " + str(te - ts))

输出:

版本A = ASYNCIO;版本B =请求

200
200
200
200
200
200
200
200
200
200
Version A: 5.7215821743011475
200
200
200
200
200
200
200
200
200
200
Version B:  5.320340156555176
python performance python-3.x benchmarking python-asyncio
3个回答
14
投票

您正在等待每个请求启动下一个之前完成。所以,你有没有好处事件循环的开销。

尝试这个:

import asyncio
import functools
import requests
import time

ts = time.time()
loop = asyncio.get_event_loop()

@asyncio.coroutine
def do_checks():
    futures = []
    for i in range(10):
        futures.append(loop.run_in_executor(None, functools.partial(requests.get, "http://google.com", timeout=3)))

    for req in asyncio.as_completed(futures):
        resp = yield from req
        print(resp.status_code)

loop.run_until_complete(do_checks())
te = time.time()
print("Version A: " + str(te - ts))

ts = time.time()
for i in range(10):
    r = requests.get("http://google.com", timeout=3)
    print(r.status_code)
te = time.time()
print("Version B:  " + str(te - ts))

这是我所得到的,当我运行它:

$ python test.py 
200
...
Version A: 0.43438172340393066
200
...
Version B: 1.6541109085083008

快得多,但实际上这只是产卵线程和等待HTTP库完成,你不需要asyncio做到这一点。

你可能想结帐qazxsw POI,因为它是与qazxsw POI使用内置。 qazxsw POI是一个神话般的图书馆,但它不是为aiohttp制造。


7
投票

只是为了完整性,这里是一个非常快ASYNCIO实施

asyncio

该代码是蟒蛇3.5及更高版本。

requests

希望有人能使用它;)


3
投票

建立在@ brunsgaard的回答是:你可以走了一步与aiohttp与asyncio收集你的结果。然后,您可以从您的要求采取的响应和处理它们。

import aiohttp
import asyncio
import time

async def main(n):
    ts = time.time()
    session = aiohttp.ClientSession()
    fs = [session.get('http://google.com') for _ in range(n)]
    for f in asyncio.as_completed(fs):
        resp = await f
        print(resp.status)
        await resp.release()
    await session.close()
    te = time.time()
    print("Aiohttp version:  " + str(te - ts))

loop = asyncio.get_event_loop()
loop.run_until_complete(main(10))
loop.close()
© www.soinside.com 2019 - 2024. All rights reserved.