как отладить асинхронную медлительность aiohttp - PullRequest
0 голосов
/ 30 января 2019

Я недавно поигрался с модулем asyncio.Ниже приведен код для отправки некоторых параллельных запросов, которые на моем ноутбуке (Mac OS) работают нормально, но на другой машине он работает медленно (Ubuntu 18.04).На машине, где она работала медленно (Ubuntu 18.04), я установил virtualbox vm с новой версией Ubuntu 18.04, и, к моему удивлению, код там работает отлично.У меня есть несколько версий Python на машине Ubuntu, и я пытаюсь запустить это с 3.7.2.Я не уверен, как сузить проблему здесь.Было бы здорово, если бы кто-то мог помочь мне в этом.

Я уверен, что это не проблема сети.На физической машине Ubuntu этот код занимает ~ 130 секунд, чтобы завершиться.Но внутри виртуальной машины Ubuntu, где она работает, как и ожидалось, это займет не более 5 секунд.

import aiohttp
import asyncio
import ssl
import time
from bs4 import BeautifulSoup


async def get_app_updated_date(html_content):
    soup = BeautifulSoup(html_content, 'lxml')
    section_titles_divs = [x for x in soup.select('div.hAyfc div.BgcNfc')]

    title_normalization = {
        'Updated': 'updated',
    }

    data = {
        'updated': None,
    }

    for title_div in section_titles_divs:
        section_title = title_div.string
        if section_title in title_normalization:
            title_key = title_normalization[section_title]
            value_div = title_div.next_sibling.select_one('span.htlgb')
            value = value_div.text
            data[title_key] = value
    return data


async def fetch(session, url, app_id):
    print(f'Fetching information for {app_id}')
    async with session.get(url, params={'id': app_id}, ssl=ssl.SSLContext()) as response:
        html_resp = await response.text()
        app_lastupdated_date = await get_app_updated_date(html_resp)
        return {app_id: app_lastupdated_date}


async def main():
    url = 'https://play.google.com/store/apps/details'
    app_list = ['com.google.android.youtube',
                'com.whatsapp',
                'com.instagram.android',
                'com.google.android.apps.maps',
                'com.kiloo.subwaysurf',
                'com.halfbrick.fruitninjafree',
                'com.adobe.reader',
                'org.mozilla.firefox',
                'com.zeptolab.ctr.ads',
                'com.fingersoft.hillclimb']
    async with aiohttp.ClientSession() as session:
        url_requests = [fetch(session, url, app_id) for app_id in app_list]
        print(url_requests)
        results = await asyncio.gather(*url_requests)
        for r in results:
            print(r)
        print(f'Result size  = {len(results)}')


if __name__ == '__main__':
    start_time = time.time()
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    print(f'Script execution completed in: {time.time() - start_time} seconds')

ОБНОВЛЕНИЕ: В соответствии с рекомендациями, прилагаю отчет о профилировщике.Не в состоянии понять жаргон.Опять же, ища опыт людей на этом форуме.

profiler_screenshot_1 profiler_screenshot_2

1 Ответ

0 голосов
/ 30 января 2019

Я предлагаю вам сузиться, чтобы хотя бы функционировать.Используйте профилирование модуль или профилировщик в вашей IDE (то есть Pycharm предоставляет довольно хорошие инструменты), чтобы понять проблемную функцию.

Но IMO, это на самом деле похоже на проблему с сетью, потому что работа под Ubuntu наголое железо это:

  • среда Python
  • реализация цикла событий
  • привязки к системным пакетам
  • сетевое взаимодействие с Ubuntu (включая преобразователь DNS)

Ubuntu в виртуальной машине:

  • среда Python
  • реализация цикла событий
  • привязки к системным пакетам
  • сеть с мостом изВиртуальная машина на хост-систему (зависит от настроек виртуальной машины)
  • Windows Network (включая DNS-преобразователь)
...