Python 实现的排序算法的性能不佳
我已经实现了一些排序算法,包括插入、选择、Shell和两种合并。我发现我的工具的性能与算法4th的描述不一致。 例如,这里有两种合并排序。对包含100000个元素的列表进行排序时,Merge1大约需要0.6秒,Merge2大约需要50秒以上。但是Merge2与Algorithms4th中的几乎相同,只是我使用python。我不明白为什么Merge2这么慢,以及如何改进它。有人能帮我吗?谢谢 第1类: def mergeself,a,b: i=0;j=0 res=[] 而iPython 实现的排序算法的性能不佳,python,sorting,Python,Sorting,我已经实现了一些排序算法,包括插入、选择、Shell和两种合并。我发现我的工具的性能与算法4th的描述不一致。 例如,这里有两种合并排序。对包含100000个元素的列表进行排序时,Merge1大约需要0.6秒,Merge2大约需要50秒以上。但是Merge2与Algorithms4th中的几乎相同,只是我使用python。我不明白为什么Merge2这么慢,以及如何改进它。有人能帮我吗?谢谢 第1类: def mergeself,a,b: i=0;j=0 res=[] 而i
Merge2需要:57.99568271636963s考虑此修改。根据我的快速测试,它大大提高了性能,从近一分钟下降到不到1秒。主要的性能增益来自于避免创建整个列表的那么多副本。其他改动只能略微提高性能。 根据一个简单的总和比较,它不应该弄乱列表,但是如果你想使用它,你应该做更多的测试
class Merge4:
def merge(self, source, aux, lo, mid ,hi):
i = lo
j = mid + 1
a_j= aux[j]
a_i= aux[i]
k = lo
while k <= hi:
if i > mid:
source[k] = a_j
j += 1
a_j= aux[j]
elif j > hi:
source[k] = a_i
i += 1
a_i= aux[i]
elif a_i < a_j:
source[k] = a_i
i += 1
a_i= aux[i]
else:
source[k] = a_j
j += 1
a_j= aux[j]
k += 1
# update the aux array for the next call
aux[lo:hi+1]= source[lo:hi+1]
def sort(self, source):
sz = 1
N = len(source)
while sz < N:
sz_2= sz * 2
# create the aux array, that will be maintained continuously
# and add one extra None, so the "prefetching" works also
# during the last iteration (refering to a_i and a_j)
aux= source[:]
aux.append(None)
for lo in range(0, N-sz, sz_2):
# pdb.set_trace()
self.merge(source, aux, lo, lo+sz-1, min(lo+sz_2-1, N-1))
sz = sz_2
def is_sort(self, source):
length = len(source)
for i in range(0, length-1):
if source[i] > source[i+1]:
return False
return True
在不深入讨论算法细节的情况下,最突出的是Merge1只是用append构造一个列表,而Merge2一次修改一个现有列表中的一个元素,同时更频繁地访问列表进行比较——我认为这是解释的主要部分。与Merge1相比,Merge2看起来并不是很乐观。有一件事我突然想到了。在merge2中,aux始终填充整个阵列的一个副本,尽管该副本的实际使用范围很小。这可能会产生大量的复制和垃圾收集开销。也许你可以考虑在整个手术过程中保持一个完整的拷贝。