使用多线程访问只读字典
Accessing a read-only dictionary with multiple threads
我有一个列表 L 和包含键 K[=18= 的大字典 D ] 其中 k 是 K 中的特定键。 D[k] 包含一些我需要确定结果列表的信息。现在我正在搜索 K 中的每个值,如果那里的信息对我有价值,我将 k 附加到 L。这以迭代方式工作,但我希望我可以通过多线程加速它。字典永远不会更新。执行此操作的好方法是什么?
根据您使用的 Python 解释器,以及您在搜索字典时使用的具体方法,多线程可能不会加快速度。 cpython的Global Interpreter Lock (GIL)表示在给定时间只有一个线程可以执行python代码。
现在,如果您使用用 C 语言编写并针对性能进行了优化的库,它们可能会在执行繁重的数学工作时释放 GIL(NumPy 是 good example)。这同样适用于等待 I/O 的线程。除此之外,由于切换线程上下文会产生开销,因此多线程最终可能会变慢。
在 Python 中,使用 multi-processing 通常可以获得更好的结果。每个进程都有自己的 GIL,因此代码可以 运行 并行。假设您的字典确实是只读的,那么将字典的副本提供给每个生成的进程就足够了。
多处理的缺点是线程之间的通信涉及更多的开销,因此执行越独立,您看到的结果就越好。还值得注意的是,Windows 往往有一个 higher cost associated 产生新的进程,但这不应该是任何 CPU 的问题-绑定为你将拥有的进程数可能会很小。
总体思路是MapReduce or Producer-Consumer模式:
地图Phase/Producer:
将搜索 space 除以要生成的进程数(即,对于四个进程,每个进程获得 1/4 的键以及对字典的引用)。
Reduce/Consumer:
当进程找到命中时,它会将值发送到线程安全队列。
当所有进程都完成工作后,您的队列将保存结果。
几乎可以肯定,您会发现最省力的方法是使用 multiprocessing.Pool.map
函数 (docs)
我有一个列表 L 和包含键 K[=18= 的大字典 D ] 其中 k 是 K 中的特定键。 D[k] 包含一些我需要确定结果列表的信息。现在我正在搜索 K 中的每个值,如果那里的信息对我有价值,我将 k 附加到 L。这以迭代方式工作,但我希望我可以通过多线程加速它。字典永远不会更新。执行此操作的好方法是什么?
根据您使用的 Python 解释器,以及您在搜索字典时使用的具体方法,多线程可能不会加快速度。 cpython的Global Interpreter Lock (GIL)表示在给定时间只有一个线程可以执行python代码。
现在,如果您使用用 C 语言编写并针对性能进行了优化的库,它们可能会在执行繁重的数学工作时释放 GIL(NumPy 是 good example)。这同样适用于等待 I/O 的线程。除此之外,由于切换线程上下文会产生开销,因此多线程最终可能会变慢。
在 Python 中,使用 multi-processing 通常可以获得更好的结果。每个进程都有自己的 GIL,因此代码可以 运行 并行。假设您的字典确实是只读的,那么将字典的副本提供给每个生成的进程就足够了。
多处理的缺点是线程之间的通信涉及更多的开销,因此执行越独立,您看到的结果就越好。还值得注意的是,Windows 往往有一个 higher cost associated 产生新的进程,但这不应该是任何 CPU 的问题-绑定为你将拥有的进程数可能会很小。
总体思路是MapReduce or Producer-Consumer模式:
地图Phase/Producer: 将搜索 space 除以要生成的进程数(即,对于四个进程,每个进程获得 1/4 的键以及对字典的引用)。
Reduce/Consumer: 当进程找到命中时,它会将值发送到线程安全队列。
当所有进程都完成工作后,您的队列将保存结果。
几乎可以肯定,您会发现最省力的方法是使用 multiprocessing.Pool.map
函数 (docs)