为什么DSU decorate-sort-undecorate比提供比较功能更快?

时间:2015-08-24 16:08:42

标签: python sorting

Pythonistas喜欢谈论一种名为DSU的技术:

假设我想按第三个字段的int值排序列表:

# Decorate
decorated = [(int(item[2]), item) for item in items]
# Sort
decorated.sort()
# Undecorate
items = [item[1] for item in decorated]

据说,这种方法比以下方法更有效:

def compare(item1, item2):
    return cmp(int(item1[2]), int(item2[2]))
items.sort(compare)

为什么DSU更快?什么使sort()没有比较器特殊?

2 个答案:

答案 0 :(得分:5)

这取决于从项目到要排序的值的转换成本是多少。在这种情况下,转化是采用第三项的int

使用比较方法,每个项目转换多次。使用decorate / sort / undecorate方法,每个项目只进行一次转换。如果关键功能很昂贵,那么每个项目只调用一次应该更有效。

请注意,您可以使用内置函数执行decorate / sort / undecorate方法:

items.sort(key=lambda item: int(item[2]))

答案 1 :(得分:3)

在排序期间必须重复调用cmp函数,每次分拣机需要比较两个对象时。由于在排序期间可能必须将同一对象与多个其他对象进行比较,因此每个对象可以多次调用cmp。另一方面,使用DSU只需要为列表中的每个项目执行一次装饰代码,无论进行多少次比较。

在最新版本的Python中,您可以使用key参数sort代替:items.sort(key=lambda item: item[2])。这有效地为您做了DSU。