Почему asyncio.gather со строками DataFrame pandas не запускается одновременно?Python

Программы на Python
Anonymous
Почему asyncio.gather со строками DataFrame pandas не запускается одновременно?

Сообщение Anonymous »

Я обрабатываю большой DataFrame pandas (500 тыс. строк), где каждая строка требует HTTP-запроса. Я перешел с запросов на aiohttp + asyncio, ожидая значительного ускорения, но асинхронная версия работает так же медленно, как и синхронный цикл. Я не могу понять, где блокируется параллелизм.
Вот минимальный воспроизводимый пример:

Код: Выделить всё

import asyncio
import aiohttp
import pandas as pd
import time

# Sample DataFrame with 100 rows, each hitting a delayed endpoint
df = pd.DataFrame({
'id': range(100),
'url': ['http://httpbin.org/delay/0.1'] * 100
})

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

async def process_dataframe(df):
async with aiohttp.ClientSession() as session:
tasks = []
for _, row in df.iterrows():
task = asyncio.create_task(fetch(session, row['url'], row['id']))
tasks.append(task)
results = await asyncio.gather(*tasks)
return results

start = time.time()
results = asyncio.run(process_dataframe(df))
print(f"Async time: {time.time() - start:.2f} seconds")
Ожидается: При 100 запросах к конечной точке с задержкой 0,1 с параллелизм должен завершиться через 0,1–0,2 секунды.
Факт: Сценарий занимает 10 секунд, точно так же, как синхронный цикл.
Что я проверил:
  • Цикл событий запущен (нет ошибки RuntimeError об отсутствующем цикле).
  • установлен правильно, и нет предупреждений о блокировке DNS/резольвера.
  • Одинаковое поведение в macOS и Linux, Python 3.11 и 3.12.
Вопрос: Почему запросы не отправляются одновременно? Выполняет ли итерация по строкам DataFrame внутри асинхронной функции каким-либо образом сериализацию задач? Или существует известное ограничение при использовании asyncio.create_task в узком цикле?
Среда:
  • Python 3.11.7
  • pandas 2.1.4
  • aiohttp 3.9.1

Вернуться в «Python»