Как увеличить скорость работы в Python - PullRequest
0 голосов
/ 19 июня 2020

Итак, у меня есть эта функция:

def scan_likes(my_list):
    count = {}
    for element in my_list:
        try:
            count[element] = 0
            book = requests.get('https://booksmania.com', header = element) #list, that i get from API, no need to remake this line
            for text in book:
                if 'ok' in text:
                    count[element] += 1
        except Exception:
            pass

Итак, дело в том, что два списка: my_list и book слишком большие, поэтому функция занимает очень много времени. Есть ли вариант, как увеличить скорость, может, использовать что-нибудь вместо l oop? Спасибо!

1 Ответ

1 голос
/ 19 июня 2020

Один из вариантов - использовать aiohttp для параллельного сбора нескольких URL-адресов. Поскольку я не могу получить доступ к booksmania.com, я использую https://github.com/alexwohlbruck/cat-facts в качестве примера

Вот полный код

import asyncio
import sys
import aiohttp
import requests

url = 'https://cat-fact.herokuapp.com/facts/random'

def get_sync():
    for i in range(1,10):
        requests.get(url)
        print('.')
    print()


async def aget(session, url):
    await session.get(url)
    print('.')


async def get_async():
    async with aiohttp.ClientSession() as session:
        tasks = []
        for i in range(1,10):
            tasks.append(asyncio.create_task(aget(session, url)))

        # wait for all concurrently
        responses = await asyncio.gather(*tasks)
    print()

if __name__ == '__main__':
    if sys.argv[1]  == 'sync':
        get_sync()
    else:
        asyncio.run(get_async())

Чтобы запустить его, убедитесь, что у вас есть python 3.7, запросы (pip install requests) и aiohttp (pip install aiohttp) установлено.

Для запуска используйте python3 multiple_request.py sync для сбора всех запросов с библиотекой запросов без параллелизма и python3 multiple_requests.py async для запустите версию asyn c.

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

Теперь код ..

Функция get_sync - это то, что известно, вы просто перебираете что-то и выполняете запросы. Ничего страшного,

Функция get_async - вот что интересно вместо ожидания каждого запроса, я накапливаю все «Задачи» в массиве, а затем жду их всех параллельно * с asynio.gatther

Но что такое задача?

A Task - это то, что выполняется в фоновом режиме, и мы используем asyncio.create_ задача для их создания

Подводя итог, не вдаваясь в подробности asyncio, вместо последовательного выполнения каждого запроса мы планируем выполнение всех запросов в фоновом режиме, а затем ждем их завершения.

* параллельно: Технический термин здесь одновременно, а не параллельно. Я просто не хочу обременять объяснение еще одной концепцией.

В этом примере вы сможете преобразовать вашу проблему в asyncio. Вот хороший пост об этом в блоге https://pawelmhm.github.io/asyncio/python/aiohttp/2016/04/22/asyncio-aiohttp.html

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...