【问题标题】:Python sort using key : possible to parallelize?Python 使用键排序:可以并行化吗?
【发布时间】: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 会是一个不错的选择吗?由于 GIL threading 而导致的 AFAIK 实际上无法并行执行操作。但是,如果昂贵的性质是由于迭代长列表中的项目,threading 可以提供帮助吗?
  • 我还可以通过哪些其他方式加快速度?

注意:我仅限于 python 2.7。

编辑:添加细节

这是确切的代码。 funget_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 是一种较慢、毫无意义的冗长方式。并且没有必要将第一个参数切片为zipzip 在最短的迭代用完时停止,因此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


【解决方案1】:

为此,您需要使用允许您并行化问题的排序算法。一个很好的简单算法是归并排序。这将允许您拆分数据,对部分进行排序,然后将它们合并为最终的单线程排序。但是,除非您缓存值,否则这可能会导致计算键两次。

【讨论】:

    猜你喜欢
    • 2016-10-22
    • 1970-01-01
    • 2013-05-26
    • 2022-11-08
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 2020-04-22
    相关资源
    最近更新 更多