Какой самый быстрый способ проверить тысячи URL? - PullRequest
1 голос
/ 17 октября 2019

Мне нужно проверить не менее 20 тыс. URL-адресов, чтобы проверить, работает ли URL-адрес, и сохранить некоторые данные в базе данных.

Я уже знаю, как проверить, находится ли URL-адрес в сети и как сохранить некоторые данные вбаза данных. Но без параллелизма понадобится целая вечность, чтобы проверить все URL-адреса, так какой же самый быстрый способ проверить тысячи URL-адресов?

Я следую этому уроку: https://realpython.com/python-concurrency/, и кажется, что «многопроцессорная работа с привязкой к процессору»Версия "это самый быстрый способ сделать, но я хочу знать, если это самый быстрый способ или есть лучшие варианты.

Редактировать:

На основе ответов я буду обновлять постсравнение многопроцессорной и многопоточности

Пример 1. Вывести «Hello!»40 раз

Threading

  • С 1 потоком: 20.152419090270996 секунд
  • С 2 потоками: 10.061403036117554 секунд
  • С 4 потоками: 5.040558815002441 секунд
  • С 8 потоками: 2,515489101409912 секунд

Многопроцессорная обработка с 8 ядрами:

  • Потребовалось 3,1343798637390137 секунд

Если вы используете 8Threads будет лучше, чем Threading

Пример 2, проблема, предложенная в моем вопросе:

После нескольких тестов, если вы используете более 12 потоков, поток будет быстрее. Например, если вы хотите протестировать 40 URL-адресов и использовать потоки с 40 потоками, это будет на 50% быстрее, чем многопроцессорность с 8 ядрами

Спасибо за вашу помощь

Ответы [ 3 ]

3 голосов
/ 17 октября 2019

Я думаю, что вы должны использовать пул: пул документов

На основании некоторых результатов здесь: mp против потоков SO

Я бы сказал, всегдаиспользовать многопроцессорностьВозможно, если вы ожидаете, что ваши запросы займут много времени, тогда преимущества потокового переключения контекста преодолеют грубую силу многопроцессорности

Что-то вроде

import multiprocessing as mp
urls=['google.com', 'yahoo.com']

with mp.Pool(mp.cpu_count()) as pool:

        results=pool.map(fetch_data, urls)

Редактировать: чтобы обратиться к комментариям онабор подпроцессов, которые я показал, как запрашивать процессы, равные вашему количеству логических потоков

2 голосов
/ 17 октября 2019

Сказать, что многопроцессорность всегда является лучшим выбором, неверно, многопроцессорность лучше всего подходит только для сложных вычислений!

Лучший выбор для действий, которые не требуют сложных вычислений, а только для операций ввода / вывода, таких как запросы базы данных. или запросы удаленного веб-приложения API, является поток модуля. Потоки могут быть быстрее, чем многопроцессорные, так как многопроцессорность требует сериализации данных для отправки их дочернему процессу, в то время как промежуточные блоки используют один и тот же стек памяти.

Модуль потоков

Типичная активность вдело в том, чтобы создать входную очередь. Задайте очередь и поместите задачу (в вашем случае URL-адреса в ней) и создайте несколько рабочих, которые будут брать задачи из очереди:

import threading as thr
from queue import Queue


def work(input_q):
    """the function take task from input_q and print or return with some code changes (if you want)"""
    while True:
        item = input_q.get()
        if item == "STOP":
            break

        # else do some work here
        print("some result")


if __name__ == "__main__":
    input_q = Queue()
    urls = [...]
    threads_number = 8
    workers = [thr.Thread(target=work, args=(input_q,),) for i in range(threads_number)]
    # start workers here
    for w in workers:
        w.start

    # start delivering tasks to workers 
    for task in urls:
        input_q.put(task)

    # "poison pillow" for all workers to stop them:

    for i in range(threads_number):
        input_q.put("STOP")

    # join all workers to main thread here:

    for w in workers:
        w.join

    # show that main thread can continue

    print("Job is done.")
0 голосов
/ 24 октября 2019

В настоящее время я использую многопроцессорную обработку с очередями, она работает достаточно быстро для того, для чего я ее использую.

Как и в приведенном выше решении Artiom, я установил число процессов равным 80 (в настоящее время), используйте «рабочие»чтобы получить данные, отправить их в очереди и по окончании просмотреть полученные результаты и обработать их в зависимости от очереди.

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