我刚写的一些代码让我感到非常困惑。出乎意料的是,我发现:
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
返回类型的列表,第二个函数返回需要使用它们的 result()
方法来评估的 concurrent.futures.Future
对象列表,以获取 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
,以便利用可能的性能提升?
executor.map
的性能表现会比使用在适当的可迭代对象上映射executor.submit
并使用futures.as_completed
更差。你知道这是否属实吗? - Patrick Collinsmap
进行的计算,这是成立的。因为同一函数运行的时间通常(但不总是)相当。但是,如果您有一个具有非常不同运行时间的函数,则使用future.as_completed
可能会更快。 - Kritzefitzs = [1,2,4,8]
,然后将s = [8,4,2,1]
解决了我一些疑惑。 - Christian Pao.