所以我发现自己利用heapq
进行了一些计算。但是,对于我正在处理的问题,它运行缓慢,因为堆变得非常大。
我以为我可以选择加快速度。而不是创建一个巨大的堆,而不是堆成堆。但是,令我惊讶的是,“更高效”的代码明显变慢了。更有效的代码有更多的开销,但我真的认为它会赢得很多。在解决了这个问题后,我有两个功能可以进行相同的网络计算。 f1
是“天真”(和更快)的版本。 f2
是“改进的”(但速度较慢)版本。我在两者中做了一些随机数生成,但是我使用相同的种子,所以它实际上是一样的。
import random
import heapq
def f1():
random.seed(1)
Q=[0]
while Q:
value = heapq.heappop(Q)
#print value
if value<0.5:
for counter in range(16):
heapq.heappush(Q,value + 0.1 + (random.random()/1000))
print value
def f2():
random.seed(1)
Q=[[0]]
while Q:
subQ = heapq.heappop(Q)
value = heapq.heappop(subQ)
#print value
if subQ:
heapq.heappush(Q,subQ)
newQ = []
if value<0.5:
for counter in range(16):
newQ.append(value + 0.1 + (random.random()/1000))
heapq.heapify(newQ)
heapq.heappush(Q,newQ)
print value
为什么堆堆(f2
)运行速度明显变慢?它应该调用heappush
相同的次数,并且应用两次。但是堆的大小应该小得多,所以我预计它会跑得更快。
答案 0 :(得分:0)
所以我只是没有足够的推动代码。这是一些修改过的代码。当subQ变得非常大时,我出现的好处就出现了。
def f1(m,n):
random.seed(1)
Q=[0]
for counter in range(m):
value = heapq.heappop(Q)
#print value
for newcounter in range(n):
heapq.heappush(Q,random.random())
print value #should be the same for both methods, so this is just a test
def f2(m,n):
random.seed(1)
Q=[[0]]
for counter in range(1000000):
subQ = heapq.heappop(Q)
value = heapq.heappop(subQ)
#print value
if subQ:
heapq.heappush(Q,subQ)
newQ = []
for newcounter in range(n):
newQ.append(random.random())
heapq.heapify(newQ)
heapq.heappush(Q,newQ)
print value #should be the same for both methods, so this is just a test
当我分析f1(1000000,10)
和f2(1000000,10)
时,我的运行时间为10.7秒和14.8秒。相关细节如下:
F1:
ncalls tottime percall cumtime percall filename:lineno(function)
1000000 1.793 0.000 1.793 0.000 {_heapq.heappop}
10000000 3.856 0.000 3.856 0.000 {_heapq.heappush}
F2:
1000000 1.095 0.000 1.095 0.000 {_heapq.heapify}
2000000 2.628 0.000 2.628 0.000 {_heapq.heappop}
1999999 2.245 0.000 2.245 0.000 {_heapq.heappush}
10000000 1.114 0.000 1.114 0.000 {''追加''列表'对象}
因为额外的f2
以及heappop
和heapify
,网络append
会失败。它在heappush
上做得更好。
但是当我用更大的内部循环挑战它并运行f1(1000,100000)
和f2(1000,100000)
时,我们得到了
F1:
1000 0.015 0.000 0.015 0.000 {_heapq.heappop}
100000000 28.730 0.000 28.730 0.000 {_heapq.heappush}
F2:
1000 19.952 0.020 19.952 0.020 {_heapq.heapify}
2000 0.011 0.000 0.011 0.000 {_heapq.heappop}
1999 0.006 0.000 0.006 0.000 {_heapq.heappush}
100000000 6.977 0.000 6.977 0.000 {''追加''列表'对象}
所以我们现在在heappush
上做得更好,现在f2
运行得更快(69秒对75秒)。
事实证明,我没有足够努力地推动我的代码。我需要把事情变得足够大,以致许多对heappush的调用变得比许多调用heapify要慢。