为什么aiohttp比gevent慢得多?

Ish*_*att 2 python gevent python-requests python-asyncio aiohttp

免责声明:我是aiohttp的初学者

我正在尝试使用aiohttp异步处理get请求但事实证明它比gevent的池版本慢得多.

GEVENT VERSION

import gevent
from gevent import monkey
monkey.patch_all()
from gevent.pool import Pool

import requests
import time

def pooling_task(url):
    requests.get(url)


def pooling_main():
    start = time.time()
    pool = Pool(10)
    urls = [
        "http://google.com",
        "http://yahoo.com",
        "http://linkedin.com",
        "http://shutterfly.com",
        "http://mypublisher.com",
        "http://facebook.com"
    ]
    for url in urls:
        pool.apply_async(pooling_task, args=(url,))

    pool.join()
    end = time.time()
    print("POOL TIME {}".format(end-start))

if __name__ == '__main__':
    print("POOLING VERSION")
    pooling_main()
Run Code Online (Sandbox Code Playgroud)

输出 - 池时间6.299163818359375

以下是aiohttp版本

import aiohttp
import asyncio
import time
import uvloop

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()


async def main():
    urls = [
        "http://google.com",
        "http://yahoo.com",
        "http://linkedin.com",
        "http://shutterfly.com",
        "http://mypublisher.com",
        "http://facebook.com"]

    async with aiohttp.ClientSession() as session:
        for url in urls:
            await fetch(session, url)

if __name__ == "__main__":
    start = time.time()
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    end = time.time()
    print("Time taken {}".format(end - start))
Run Code Online (Sandbox Code Playgroud)

输出 - 所用时间为15.399710178375244

我真的不明白为什么aiohttp这么慢.至于gevent版本的request.get仍然是一个阻塞调用,但不适用于aiohttp.

我希望aiohttp版本更快.

Mik*_*mov 10

for url in urls:
    await fetch(session, url)
Run Code Online (Sandbox Code Playgroud)

await这意味着您不能在上一次完成之前开始下载下一个URL.要使所有下载并发,您应该使用asyncio.gather之类的东西.

像这样修改你的代码:

async with aiohttp.ClientSession() as session:
    await asyncio.gather(*[
        fetch(session, url)
        for url
        in urls
    ])
Run Code Online (Sandbox Code Playgroud)

你会看到巨大的加速.

  • 哦,我多么愚蠢.在for循环中,eventloop还没有运行.但是在聚集的情况下,它还有其他协同程序(通过获取产生的协同程序) (2认同)