gpt4 book ai didi

python - ThreadPoolExecutor().map 与 ThreadPoolExecutor().submit 有何不同?

转载 作者:IT老高 更新时间:2023-10-28 21:52:18 51 4
gpt4 key购买 nike

我只是对我编写的一些代码感到非常困惑。我惊讶地发现:

with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(f, iterable))

with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
results = list(map(lambda x: executor.submit(f, x), iterable))

产生不同的结果。第一个生成 f 返回的任何类型的列表,第二个生成 concurrent.futures.Future 对象的列表,然后需要使用它们的 result 进行评估() 方法以获取 f 返回的值。

我主要担心的是,这意味着 executor.map 无法利用 concurrent.futures.as_completed,这似乎是评估我正在对数据库进行一些长期调用的结果,这些调用是可用的。

我完全不清楚 concurrent.futures.ThreadPoolExecutor 对象是如何工作的——天真地说,我更喜欢(稍微冗长一些):

with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
result_futures = list(map(lambda x: executor.submit(f, x), iterable))
results = [f.result() for f in futures.as_completed(result_futures)]

在更简洁的 executor.map 之上,以便利用可能的性能增益。我这样做有错吗?

最佳答案

问题是您将 ThreadPoolExecutor.map 的结果转换为列表。如果您不这样做,而是直接迭代生成的生成器,结果仍会按原始顺序生成,但循环会在所有结果准备好之前继续。你可以用这个例子来测试:

import time
import concurrent.futures

e = concurrent.futures.ThreadPoolExecutor(4)
s = range(10)
for i in e.map(time.sleep, s):
print(i)

保留该顺序的原因可能是因为有时按照您为映射提供的相同顺序获得结果很重要。并且结果可能不会包含在未来的对象中,因为在某些情况下,如果您需要它们,可能需要太长时间才能在列表上执行另一个映射以获取所有结果。毕竟在大多数情况下,下一个值很可能在循环处理第一个值之前就准备好了。这在这个例子中得到了证明:

import concurrent.futures

executor = concurrent.futures.ThreadPoolExecutor() # Or ProcessPoolExecutor
data = some_huge_list()
results = executor.map(crunch_number, data)
finals = []

for value in results:
finals.append(do_some_stuff(value))

在此示例中,do_some_stuff 可能比 crunch_number 花费更长的时间,如果确实如此,那么在您仍然保留 map 使用方便。

此外,由于工作线程(/进程)从列表的开头开始处理并一直工作到您提交的列表的末尾,因此结果应该按照迭代器已经产生的顺序完成。这意味着在大多数情况下 executor.map 很好,但在某些情况下,例如,如果您处理传递给 map< 的值和函数的顺序无关紧要 运行时间非常不同,future.as_completed 可能更快。

关于python - ThreadPoolExecutor().map 与 ThreadPoolExecutor().submit 有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20838162/

51 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com