Поэтому для некоторых расчетов я пользуюсь heapq
. Однако для проблемы, над которой я работаю, она работает медленно, потому что куча становится довольно большой.улучшение эффективности 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
столько же раз, сколько и два раза. Но размер куч должен быть значительно меньше, поэтому я ожидал, что он будет работать быстрее.
написать большую стоимость O для каждой операции и сравнить, например, heapify (newQ) - O (len (newQ)), heappop(), heappush() - стоимость сравнения O (log len (Q) *), где стоимость сравнения является O (1) для float и O (len (newQ)) для вложенных куч. – jfs
@ J.F.Sebastian Почему для сравнения двух списков должно быть O (len (newQ))? Я бы ожидал, что он просто посмотрит на первую запись в списке и сортирует по этому вопросу - я ожидал, что это будет O (1). (во всех сравнениях списки отличаются в их первой записи) – Joel
, если они * всегда * отличаются друг от друга, то это также O (1), и только постоянный коэффициент может быть другим. Попробуйте изменить алгоритм, чтобы увеличить размер кучи, чтобы увидеть фактический ростный полином ([пример] (http://stackoverflow.com/a/482848/4279)). – jfs