улучшая скорость «Отправка 100 000 запросов» от asyncio, используя многопроцессорные и многопоточные

Прежде всего, я хочу как можно быстрее отправить несколько запросов, используя 1 соединение. Код ниже работает отлично и быстро, но я хочу, чтобы он вышел за рамки асинхронного. Вернемся к моему вопросу, можно ли запустить это параллельно, используя многопоточную или многопроцессорную обработку. Я слышал, что вы можете использовать ThreadPoolExecutor или ProcessPoolExecutor.

import random import asyncio from aiohttp import ClientSession import time from concurrent.futures import ProcessPoolExecutor async def fetch(sem,url, session): async with sem: async with session.get(url) as response: return await response.read() async def run(r): url = "http://www.example.com/" tasks = [] sem = asyncio.Semaphore(1000) async with ClientSession() as session: for i in range(r): task = asyncio.ensure_future(fetch(sem, url.format(i), session)) #return a task tasks.append(task) responses = asyncio.gather(*tasks) await responses if __name__ == "__main__": number = 10000 loop = asyncio.get_event_loop() start = time.time() loop.run_until_complete(run(number)) end = time.time() - start print (end) 

от тестирования ему удалось отправить примерно 10 тыс. запросов в 49сек. Мне нужно, чтобы это было быстрее, любое предложение? (поток, процесс)

ProcessPoolExecutor – это способ выполнения реальной многопроцессорной обработки. Для вашего прецедента это в основном так же, как если бы вы запускали несколько копий своей программы одновременно. Если на вашем компьютере имеется пропускная способность и требуемый центральный процессор, вы можете повысить производительность на 4 с помощью ProcessPoolExecutor (max_workers = 4)

Однако вам понадобится цикл событий asyncio в каждом из подпроцессов, поэтому вы можете сделать что-то вроде этого:

 def main(n): loop = asyncio.get_event_loop() loop.run_until_complete(run(n)) with concurrent.futures.ProcessPoolExecutor(max_workers=4) as exc: exc.submit(main, 2500) exc.submit(main, 2500) exc.submit(main, 2500) exc.submit(main, 2500) 

В качестве побочной заметки о вашей функции run : вам также не нужно использовать ensure_future или Tasks, результатом функции async def является сопрограмма, которую вы непосредственно asyncio.gather или передаете asyncio.gather

 async def run(r): url = "http://www.example.com/" sem = asyncio.Semaphore(1000) async with ClientSession() as session: coros = [fetch(sem, url.format(i), session) for i in range(r)] await asyncio.gather(*coros)