Это потому, что этот
for key in d:
if len(d) > 1 or -1 not in d:
break
сломается на первой итерации, поэтому ваш внутренний l oop в основном не работает.
Добавление del[i]
заставляет его делать некоторые реальная работа, которая требует времени.
Обновление: хорошо вышеприведенный, очевидно, способ упрощения c: -)
Следующая версия вашего кода показывает то же самое характеристика c:
import time
import gc
n = 140000
def main(d):
for i in range(n):
del d[i] # A
for key in d: # B
break # B
import dis
d = dict()
for i in range(n):
d[i] = "DUMMY"
print dis.dis(main)
start_time = time.time()
main(d)
print("--- {} seconds ---".format(time.time() - start_time))
Использование iterkeys не имеет значения.
Если мы построим график времени выполнения для различных размеров n
, мы получим (n на x- ось, в секундах по оси y):
, поэтому явно происходит экспоненциальное изменение.
Удаление линии (A) или линии (B) удаляют экспоненциальный компонент, хотя я не уверен, почему.
Обновление 2: На основании ответа @ Blckknght мы можем восстановить некоторую скорость, нечасто перефразируя элементы :
def main(d):
for i in range(n):
del d[i]
if i % 5000 == 0:
d = {k:v for k, v in d.items()}
for key in d:
break
или это:
def main(d):
for i in range(n):
del d[i]
if i % 6000 == 0:
d = {k:v for k, v in d.items()}
try:
iter(d).next()
except StopIteration:
pass
занимает меньше половины времени оригинала при большом n (выпуклость на 130000 соответствует объему r 4 работает ..).