Python вложен для цикла быстрее, чем одиночный для цикла - PullRequest
0 голосов
/ 12 ноября 2018

Почему вложенный цикл for быстрее, чем единственный цикл for?

start = time()

k = 0
m = 0

for i in range(1000):
    for j in range(1000):
        for l in range(100):
            m+=1

#for i in range(100000000):
#    k +=1

print int(time() - start)

Для одиночного цикла for я получаю время 14 секунд, а для вложенного цикла 10 секунд

Ответы [ 4 ]

0 голосов
/ 12 ноября 2018

Соответствующий контекст объясняется в этой теме.

Короче говоря, range(100000000) создает огромный список в Python 2, тогда как с помощью вложенных циклов вы строите списки только с 1000 + 1000 + 100 = 2100 элементов. В Python 3 range умнее и ленивее, как xrange в Python 2.

Вот некоторые моменты времени для следующего кода. Абсолютное время выполнения зависит от системы, но сравнение значений друг с другом является ценным.

import timeit

runs = 100

code = '''k = 0
for i in range(1000):
    for j in range(1000):
        for l in range(100):
            k += 1'''

print(timeit.timeit(stmt=code, number=runs))

code = '''k = 0
for i in range(100000000):
    k += 1'''

print(timeit.timeit(stmt=code, number=runs))

Выходы:

CPython 2.7 - range

264.650791883
372.886064053

Интерпретация: создание огромных списков требует времени.

CPython 2.7 - range заменяется на xrange

231.975350142
221.832423925

Интерпретация: почти равная, как и ожидалось. (Вложенные for петли должны иметь слегка большие накладные расходы, чем один for цикл.)

CPython 3.6 - range

365.20924194483086
437.26447860104963

Интерпретация: Интересно! Я не ожидал этого. Кто-нибудь?

0 голосов
/ 12 ноября 2018

В Python 2 range создает список со всеми числами в списке. Попробуйте поменять range на xrange, и вы увидите, что они занимают сравнимое время, иначе подход с одним циклом может работать немного быстрее.

0 голосов
/ 12 ноября 2018

во время вложенных циклов питон должен выделить 1000+1000+100=2100 значения для счетчиков, тогда как в одиночном цикле он должен выделить 10M.Это то, что занимает дополнительное время

Я проверил это в Python 3.6, и поведение аналогично, я бы сказал, что очень вероятно, что это проблема выделения памяти.

0 голосов
/ 12 ноября 2018

Это потому, что вы используете Python2. Range генерирует список чисел и должен выделить этот список. В первом вложенном цикле вы выделяете 1000 + 1000 + 100, поэтому размер списка равен 2100, а во втором - размер списка 100000000, что намного больше.

В python2 лучше использовать generator, xrange(), генератор выдает числа, а не строит и выделяет из них список.

Дополнительно и для получения дополнительной информации вы можете прочитать этот вопрос , что он связан с этим, но в python3

...