繁体   English   中英

检查数千个网址的最快方法是什么?

[英]What's the fastest way to check thousands of urls?

我需要检查至少 20k 个 url 以检查 url 是否已启动并将一些数据保存在数据库中。

我已经知道如何检查 url 是否在线以及如何在数据库中保存一些数据。 但是如果没有并发,检查所有 url 需要很长时间,那么检查数千个 url 的最快方法是什么?

我正在关注本教程: https://realpython.com/python-concurrency/似乎“CPU-Bound multiprocessing Version”是最快的方法,但我想知道这是最快的方法还是有更好的选择。

编辑:

根据回复,我将更新比较多处理和多线程的帖子

示例 1:打印“你好!” 40次

穿线

  • 使用 1 个线程:20.152419090270996 秒
  • 有 2 个线程:10.061403036117554 秒
  • 有 4 个线程:5.040558815002441 秒
  • 8个线程:2.515489101409912秒

8核多处理:

  • 花了 3.1343798637390137 秒

如果你使用 8 个线程,线程会更好

示例2,我的问题中提出的问题:

经过多次测试,如果您使用超过 12 个线程,线程会更快。 例如,如果您想测试 40 个 url,并且使用 40 个线程的线程,它将比 8 核的多处理快 50%

谢谢你的帮助

我认为你应该使用 pool: pool docs

基于这里的一些结果: mp vs threading SO

我会说总是使用多处理。 也许如果您希望您的请求需要很长时间才能解决,那么线程的上下文切换优势将克服多处理的蛮力

就像是

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

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

        results=pool.map(fetch_data, urls)

编辑:为了解决关于一组子进程的评论,我已经展示了如何请求进程等于你的逻辑线程数

说多处理总是最好的选择是不正确的,多处理只适用于繁重的计算!

对于不需要大量计算而只需要输入/输出操作(如数据库请求或远程 web 应用程序 api 的请求)的操作,最佳选择是模块线程。 线程可以比多处理更快,因为多处理需要序列化数据以将其发送到子进程,同时 trheads 使用相同的 memory 堆栈。

线程模块

该案例中的典型活动是创建输入 queue.Queue 并放置任务(在您的案例中为 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.")

我目前使用带队列的多处理,它的运行速度足以满足我的用途。

与上述 Artiom 的解决方案类似,我将进程数设置为 80(当前),使用“workers”拉数据,将其发送到队列,一旦完成,go 通过返回的结果并根据队列处理它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM