【发布时间】:2017-01-23 22:33:13
【问题描述】:
我做了功课,无意中发现算法的速度有一个奇怪的不一致。 这是相同函数 bur 的 2 个版本的代码,但有 1 个不同:在第一个版本中,我使用 3 次数组生成器来过滤一些数组,在第二个版本中,我使用 1 个 for 循环和 3 个 if 语句来执行相同的过滤工作。
所以,这里是第一个版本的代码:
def kth_order_statistic(array, k):
pivot = (array[0] + array[len(array) - 1]) // 2
l = [x for x in array if x < pivot]
m = [x for x in array if x == pivot]
r = [x for x in array if x > pivot]
if k <= len(l):
return kth_order_statistic(l, k)
elif k > len(l) + len(m):
return kth_order_statistic(r, k - len(l) - len(m))
else:
return m[0]
这里是第二版的代码:
def kth_order_statistic2(array, k):
pivot = (array[0] + array[len(array) - 1]) // 2
l = []
m = []
r = []
for x in array:
if x < pivot:
l.append(x)
elif x > pivot:
r.append(x)
else:
m.append(x)
if k <= len(l):
return kth_order_statistic2(l, k)
elif k > len(l) + len(m):
return kth_order_statistic2(r, k - len(l) - len(m))
else:
return m[0]
第一个版本的 IPython 输出:
In [4]: %%timeit
...: A = range(100000)
...: shuffle(A)
...: k = randint(1, len(A)-1)
...: order_statisctic(A, k)
...:
10 loops, best of 3: 120 ms per loop
对于第二个版本:
In [5]: %%timeit
...: A = range(100000)
...: shuffle(A)
...: k = randint(1, len(A)-1)
...: kth_order_statistic2(A, k)
...:
10 loops, best of 3: 169 ms per loop
那么为什么第一个版本比第二个版本快?我还使用 filter() 函数而不是数组生成器制作了第三个版本,它比第二个版本慢(每个循环有 218 毫秒)
【问题讨论】:
-
列表推导通常比等效的 for 循环更快。扩展列表(您的附加函数)也可能比填充已知大小的列表更昂贵。
-
显着增加您的列表大小...我想您会发现差距或多或少是恒定的...您正在用空间换时间,但它们大致等价的(生成器/迭代器与列表相比有一点开销)
-
对于
A的不同随机排序和k的不同值,时间可能会有很大差异。确保在这两种情况下都为 sameA和k计时。我想你会发现差别很小。 -
你在
kth_order_statistic2中打电话给kth_order_statistic -
你真的应该使用
numpy。
标签: python arrays python-2.7 time list-comprehension