【问题标题】:Should i use multi-threading? (retrieving mass data from APIs)我应该使用多线程吗? (从 API 中检索海量数据)
【发布时间】:2023-03-06 23:17:02
【问题描述】:

我有一个 python 脚本,它从一个 API 收集 10,000 个“人”,然后继续请求另外两个 API 收集有关他们的更多数据,然后将信息保存到本地数据库,大约需要 0.9 秒每人。

所以目前需要很长时间才能完成。多线程有助于加快速度吗?我在本地尝试了一个多线程测试,速度较慢,但​​这个测试只是一个简单的函数,没有任何 API 交互或任何与 web/disk 相关的内容。

谢谢

【问题讨论】:

  • 你在说什么 API?
  • 假设 API 访问远程服务器或“慢”本地资源(如磁盘绑定数据库),并且假设您的客户端本身有空闲资源,并发可能是解决问题的方法去吧。
  • 你应该查找python GIL(全局解释器锁)。我还没有测试自己的性能,但我希望 Python 脚本的性能不会因为添加更多线程而有太大提高。 I/O 绑定线程将比计算绑定线程做得更好 - 因此,如果您的脚本主要是 IO 绑定,那么添加线程很可能会提高其性能。对于计算绑定脚本,多处理会做得更好——在几个进程中运行脚本,每个进程都做一些工作。

标签: python multithreading


【解决方案1】:

你有多少个内核?

流程的可并行性如何?

问题是 CPU 受限吗?

如果您有多个内核并且可以在它们之间进行并行处理,那么您可能会获得速度提升。除非执行得非常好,否则多线程的开销不会接近 100%,所以这是一个加分项。

另一方面,如果慢速部分受 CPU 限制,那么研究 C 扩展或 Cython 可能会更有成效。这两者有时都可以提供 100 倍的加速(有时更多,通常更少,取决于代码的数字),而比使用 multiprocessing 的 2 倍加速要少得多。显然 100 倍的加速只是针对翻译后的代码。

但是,说真的,个人资料。很可能有比这更容易获得的低垂果实。试试线分析器(比如说,一个叫做line_profiler [也叫做kernprof])和内置的cProfile。

【讨论】:

  • 4 核。我看不出它是如何受到限制的,已经进行了检查以防止收集重复项。 CPU负载很低,我认为主要的等待时间是外部APIs
  • 然后你应该并行化 API 调用,基本线程(参见threading 或更新的concurrent.futures)会更容易处理。如果您不受 CPU 限制,则多个进程毫无意义。
  • 我认为整个任务确实需要线程化,因为“人”是更高级别的一部分。之后再检索,大概有200万个类别。
  • 我认为这个答案忽略了一个大问题:往返延迟。如果您请求一些数据然后等待响应,这将花费您至少与 ping 一样多的费用。如果您花时间通过发送更多请求来等待响应,那么您正在更好地利用网络。如果您有很多小的请求/响应对,那么往返延迟可能是幼稚设计中的性能杀手。
猜你喜欢
  • 2016-07-02
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多