编辑
2024-07-05
👨‍🎓 无限进步
00
请注意,本文编写于 349 天前,最后修改于 225 天前,其中某些信息可能已经过时。

目录

How to Choose The Method
1. One Task Vs Multiple Tasks
2. Blocking vs Non-Blocking
3. Lazy vs Non-lazy
4. Single Arguments vs Multiple Arguments
5. Ordered Results vs Unordered Results
6. Result Callback vs No Result Callbacks
Compare Methods
1. apply vs apply_async
2. map vs map_async
3. imap vs imap_unordered
4. starmap vs starmap_async
5. pool.map vs built-in map()
6. pool.starmap() vs itertools.starmap()
7. imap() vs map()
Common Questions
1. How to Issue a single Task to the Process Pool
2. how to issue Tasks When the Target Function has no arguments
3. how to call map() for a function with multiple Arguments
4. how to issue tasks Asynchronously
5. is the imap_unordered() Asynchronous?
6. is there a imap_async() Function
7. why Ever use apply()
8. How do you call many different Target Functions
9. why bother use imap() instead of map
10. how do you best set chunksize?

How to Choose The Method

1. One Task Vs Multiple Tasks

可以通过指定目标函数和每次调用目标函数的参数可迭代对象来向进程池发出多个调用。可以通过以下函数实现这一点:map()、map_async()、imap()、imap_async()、starmap() 和 starmap_async()。

发出单个任务:

  • 使用 apply()
  • 使用 apply_async()

发出多个任务:

  • 使用 map()
  • 使用 map_async()
  • 使用 imap()
  • 使用 imap_unordered()
  • 使用 starmap()
  • 使用 starmap_async()

2. Blocking vs Non-Blocking

阻塞调用:

  • 使用 apply()
  • 使用 map()
  • 使用 starmap()

非阻塞调用:

  • 使用 apply_async()
  • 使用 map_async()
  • 使用 imap()
  • 使用 imap_unordered()
  • 使用 starmap_async()

3. Lazy vs Non-lazy

它们立即向进程池发出所有任务。这意味着提供的可迭代对象被遍历,并且所有对目标函数和产生的参数的调用都被转换成任务并保存在内存中。

我们可以将这些函数称为非惰性的。它们包括 map()、map_async()、starmap() 和 starmap_async()。

其他函数则逐一向进程池发出任务,只有在进程池中有空闲空间执行新任务时才会发出。这意味着提供的可迭代对象会逐个遍历,按需创建和发出任务。

我们可以将这些函数称为惰性的,可能更节省内存。它们包括 imap() 和 imap_unordered()。

惰性调用(逐一):

  • 使用 imap()
  • 使用 imap_unordered()

非惰性调用(一次性):

  • 使用 apply()
  • 使用 apply_async()
  • 使用 map()
  • 使用 map_async()
  • 使用 starmap()
  • 使用 starmap_async()

4. Single Arguments vs Multiple Arguments

没有参数的目标函数:

  • 使用 apply()
  • 使用 apply_async()

带有一个参数的目标函数:

  • 使用 apply()

  • 使用 apply_async()

  • 使用 map()

  • 使用 map_async()

  • 使用 imap()

  • 使用 imap_unordered()

  • 使用 starmap()

  • 使用 starmap_async() 具有多个参数的目标函数:

  • 使用 apply()

  • 使用 apply_async()

  • 使用 starmap()

  • 使用 starmap_async()

5. Ordered Results vs Unordered Results

有序结果:

  • 使用 map()
  • 使用 map_async()
  • 使用 imap()
  • 使用 starmap()
  • 使用 starmap_async()

无序结果:

  • 使用 imap_unordered()

6. Result Callback vs No Result Callbacks

支持回调函数:

  • 使用 apply_async()
  • 使用 map_async()
  • 使用 starmap_async()

不支持回调函数:

  • 使用 apply()
  • 使用 map()
  • 使用 imap()
  • 使用 imap_unordered()
  • 使用 starmap()

Compare Methods

1. apply vs apply_async

apply() 和 apply_async() 都可以用于向进程池发出一次性任务。

它们的主要区别如下:

  • apply() 函数会阻塞,而 apply_async() 函数不会阻塞。
  • apply() 函数会返回目标函数的结果,而 apply_async() 函数会返回一个 AsyncResult 对象。
  • apply() 函数不支持回调函数,而 apply_async() 函数支持回调函数。

2. map vs map_async

map() 和 map_async() 都可以用于通过进程池向可迭代对象中的所有项发出调用函数的任务。

它们的主要区别如下:

  • map() 函数会阻塞,而 map_async() 函数不会阻塞。
  • map() 函数会返回从目标函数返回的可迭代对象,而 map_async() 函数会返回一个 AsyncResult 对象。
  • map() 函数不支持回调函数,而 map_async() 函数可以在返回值和错误上执行回调函数。

3. imap vs imap_unordered

imap() 和 imap_unordered() 函数有很多共同点,例如:

  • imap() 和 imap_unordered() 都可以通过进程池向可迭代对象中的所有项发出调用函数的任务。
  • imap() 和 imap_unordered() 都是 map() 函数的惰性版本。
  • imap() 和 imap_unordered() 函数都会立即返回一个返回值的可迭代对象。

然而,这两个函数之间有一个关键的区别:

  • imap() 返回的可迭代对象会按照任务完成的顺序逐个产生结果,而 imap_unordered() 函数则会以任务完成的任意顺序产生结果。

4. starmap vs starmap_async

starmap() 和 starmap_async() 都可以用于通过进程池发出调用带有多个参数的函数的任务。

它们的主要区别如下:

  • starmap() 函数会阻塞,而 starmap_async() 函数不会阻塞。
  • starmap() 函数会返回从目标函数返回的可迭代对象,而 starmap_async() 函数会返回一个 AsyncResult 对象。
  • starmap() 函数不支持回调函数,而 starmap_async() 函数可以在返回值和错误上执行回调函数。

5. pool.map vs built-in map()

Pool.map() 函数和内置的 map() 函数都可以遍历提供的可迭代对象,并调用目标函数,将可迭代对象的每个项传递给目标函数执行。

它们的主要区别如下:

  • Pool.map() 函数会立即遍历可迭代对象以发出所有任务,而内置的 map() 函数是惰性的,只有在遍历从目标函数返回的返回值的可迭代对象时才会遍历输入的可迭代对象。
  • Pool.map() 函数会使用子进程并行执行每个调用目标函数的任务,而内置的 map() 函数会在当前进程中执行每个调用目标函数的任务。
  • Pool.map() 函数支持单个可迭代对象作为目标函数的参数,而内置的 map() 函数支持多个可迭代对象,每个可迭代对象对应目标函数的一个参数。
  • Pool.map() 函数支持指定块大小(chunksize)来批量调用目标函数的任务,而内置的 map() 函数不支持批量调用目标函数的任务。

6. pool.starmap() vs itertools.starmap()

Pool.starmap() 和 itertools.starmap() 函数都执行一个目标函数,该函数可能具有多个参数,使用一个提供的可迭代对象,其中每个项都是一个参数迭代器,用于每个函数调用的参数。

它们的主要区别如下:

  • Pool.starmap() 函数会立即遍历可迭代对象以发出所有任务,而内置的 itertools.starmap() 函数是惰性的,只有在遍历从目标函数返回的返回值的可迭代对象时才会遍历输入的可迭代对象。
  • Pool.starmap() 函数会使用子进程并行执行每个调用目标函数的任务,而内置的 itertools.starmap() 函数会在当前进程中执行每个调用目标函数的任务。
  • Pool.starmap() 函数支持指定块大小(chunksize)来批量调用目标函数的任务,而 itertools.starmap() 函数不支持批量调用目标函数的任务。

7. imap() vs map()

imap() 和 map() 都可以用于通过进程池向可迭代对象中的所有项发出调用函数的任务。

它们的主要区别如下:

  • imap() 函数逐一向进程池发出任务,而 map() 函数一次性向进程池发出所有任务。
  • 在遍历返回值时,imap() 函数会阻塞直到每个任务完成,而 map() 函数会阻塞直到所有任务完成。

Common Questions

1. How to Issue a single Task to the Process Pool

您可以使用 apply() 或 apply_async() 函数向进程池发出单个任务。

2. how to issue Tasks When the Target Function has no arguments

您可以使用 apply() 或 apply_async() 函数发出调用无参数目标函数的任务。

3. how to call map() for a function with multiple Arguments

您可以使用 starmap() 或 starmap_async() 函数向进程池发出针对接受多个参数的目标函数的任务。

4. how to issue tasks Asynchronously

您可以使用 apply_async()、map_async() 和 starmap_async() 函数异步向进程池发出任务。

此外,imap() 和 imap_unordered() 函数不会阻塞。

5. is the imap_unordered() Asynchronous?

不完全正确,但有点像。

imap_unordered() 的异步性质不同于 apply_async()、map_async() 和 starmap_async() 函数。具体来说,imap_unordered() 函数不会返回 AsyncResult 对象。

然而,imap_unordered() 函数和 imap() 函数一样,也不会阻塞。它会立即返回,并且只有在尝试通过遍历返回的可迭代对象来获取任务结果时才会阻塞。

因此,可以说imap_unordered()函数可以异步使用。

6. is there a imap_async() Function

No

这可能是因为 API 提供的 imap_unordered() 函数本身就是异步的,因为它不会阻塞。然而,imap_unordered() 函数确实不会返回 AsyncResult 对象。

7. why Ever use apply()

如果调用 apply() 会阻塞,为什么还要使用它呢?为什么不直接调用函数呢?

主要原因是为了让函数调用在一个单独的子进程中执行。

8. How do you call many different Target Functions

我们可以使用 apply() 或 apply_async() 在循环中调用多个不同的目标函数。

我们也可以使用多个分开的调用来通过 map()、map_async()、imap()、imap_unordered()、starmap() 和 starmap_async() 函数调用多个不同的函数。

9. why bother use imap() instead of map

您会使用 imap() 而不是 map(),这样可以在结果可用时立即开始处理,而不是阻塞等待所有结果可用。

此外,imap() 使用更少的内存,因为它会延迟遍历提供的输入可迭代对象,根据需要逐步发出任务。

10. how do you best set chunksize?

map()、imap() 和 starmap() 函数都接受一个 "chunksize" 参数。

chunksize 指定了要分组并发送到工作子进程中的目标函数调用的数量。

这可以通过减少将数据参数发送到子进程和从子进程接收结果的计算开销,加速整体任务的执行。

最佳的 chunksize 值取决于您的应用程序,具体取决于正在执行的任务、它们的持续时间、发送到每个任务的数据以及从每个任务返回的数据。

您可以通过一些试验和仔细的基准测试找到最佳的 chunksize 值。

一些可以尝试的值包括:

  • chunksize=1,即不分块的默认值。
  • chunksize = 任务数 / 工作进程数,平均分配。
  • chunksize = 任务数 / 工作进程数 * 0.25,稍微少于平均分配的一部分。

本文作者:Eric

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!