【发布时间】:2018-07-14 12:38:49
【问题描述】:
假设我有一个列表列表my_list。
我想对my_list 的每个元素进行一些操作对my_list 进行排序,这也是一个列表(我们称它们为inner_list)。
def fun(inner_list):
# do some calculation on inner list
time.sleep(1) # simulate expensive operation
return cost
sorted_list = sorted(my_list, key=lambda inner_list: fun(inner_list))
- 既然
fun在时间上是昂贵的,有没有办法并行使用fun来计算成本?如果是,threading会是一个不错的选择吗?由于 GILthreading而导致的 AFAIK 实际上无法并行执行操作。但是,如果昂贵的性质是由于迭代长列表中的项目,threading可以提供帮助吗? - 我还可以通过哪些其他方式加快速度?
注意:我仅限于 python 2.7。
编辑:添加细节
这是确切的代码。 fun 是 get_delay 的抽象。 graph 是一个networkx 图,每个链接(u, v) 对delay 都有一些价值。基本上,我正在迭代路径上的所有边缘并计算累积延迟。 path 是节点列表。例如,如果 path = [1, 2, 3, 4] 则 (u, v) 链接将是 [ (1, 2) , (2, 3), (3, 4)]。
def get_delay(path):
return sum([float(graph.get_edge_data(u, v)['delay']) for u, v in zip(path[:-1], path[1:])])
【问题讨论】:
-
你能告诉我们更多关于
fun的作用以及它的输出是什么(甚至可能发布它的代码)吗?最好的解决方案很可能取决于fun的确切性质(它受 GIL 影响的程度,它的输出有多大,诸如此类)。 -
添加了详细信息。请参阅编辑。
-
fun为每个内部列表调用一次。你说得对,threading在这里无济于事。我们可以假设my_list中的每个inner_list都是唯一的吗? -
是的。每个
inner_list代表一个唯一路径。 -
旁注:
key=lambda inner_list: fun(inner_list)拼写key=fun是一种较慢、毫无意义的冗长方式。并且没有必要将第一个参数切片为zip;zip在最短的迭代用完时停止,因此zip(path[:-1], path[1:])可以避免不必要的切片,同时与zip(path, path[1:])表现相同。此外,还有一个小的优化:在 Python 2 上,始终使用itertools.izip(或等效地,使用from future_builtins import zip替换zip)以避免在您只需要迭代压缩输出时出现不必要的临时list。
标签: python multithreading python-2.7 parallel-processing