производительность python3: цикл с использованием range () против обычного while () - PullRequest
0 голосов
/ 25 декабря 2018

В Python3 я нахожу, что если я заменю

для i в диапазоне (n):

с

в то время как я

я получаю значительный выигрыш во время выполнения.Мой цикл сам по себе не мясистый, когда он выполняет несколько основных арифметических операций.

Есть ли какие-либо указатели на то, почему я вижу это поведение?

Редактировать: n находится в диапазоне 10 с от K, 10K, 12Kи т.д. Время, которое я наблюдаю, составляет .19s для 12K, .12s для 10K с циклом while.В то время как с циклом 'while', я вижу .11s для 12K, .08s для 10K.Вот моя программа:

target = 0
i = 1
#for i in range(1, n+1):
while i < n+1:
    target += i * (2 ** (i - 1)) + (i * (i + 1))//2
    i += 1

return target % (10 ** 9 + 7)

1 Ответ

0 голосов
/ 25 декабря 2018

range включает в себя небольшое количество фиксированных накладных расходов (для поиска range, сначала в глобальных, затем во встроенных модулях, затем в стоимости отправки общего вызова функции и выделения / инициализации объекта);если n достаточно мало, оно не будет компенсировано сниженной стоимостью за цикл:

In [1]: %%timeit -r5 n = 3
   ...: for i in range(n):
   ...:     pass
   ...:
365 ns ± 15.1 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

In [2]: %%timeit -r5 n = 3
   ...: i = 0
   ...: while i < n:
   ...:     i += 1
   ...:
252 ns ± 16.9 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

Но когда n достигает даже умеренного размера, уменьшенные накладные расходы на элемент окупаются:

In [3]: %%timeit -r5 n = 10
   ...: for i in range(n):
   ...:     pass
   ...:
461 ns ± 18.1 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

In [4]: %%timeit -r5 n = 10
   ...: i = 0
   ...: while i < n:
   ...:     i += 1
   ...:
788 ns ± 73.6 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

range включает более высокие постоянные затраты, но более низкие затраты на единицу, вот и все.

...