Скажите, что вам нужно выполнить вычисление с использованием 2 или даже 3 петель. Интуитивно можно сказать, что более эффективно это делать с помощью одного цикла. Я попытался простой пример Python:Число циклов имеет значение эффективности (интерпретируется как скомпилированные языки?)
import itertools
import timeit
def case1(n):
c = 0
for i in range(n):
c += 1
return c
def case2(n):
c = 0
for i in range(n):
for j in range(n):
for k in range(n):
c += 1
return c
print(case1(1000))
print(case2(10))
if __name__ == '__main__':
import timeit
print(timeit.timeit("case1(1000)", setup="from __main__ import case1", number=10000))
print(timeit.timeit("case2(10)", setup="from __main__ import case2", number=10000))
Этот код запуска:
$ python3 code.py
1000
1000
0.8281264099932741
1.04944919400441
Так эффективно 1 цикл, кажется, немного более эффективным. Тем не менее, у меня есть немного другой сценарий в моей проблеме, так как мне нужно использовать значения в массиве (в следующем примере я использую функцию range
для упрощения). То есть, если я сворачиваю все в один цикл, мне придется создать расширенный массив из значений другого массива размером от 2 до 10 элементов.
import itertools
import timeit
def case1(n):
b = [i * j * k for i, j, k in itertools.product(range(n), repeat=3)]
c = 0
for i in range(len(b)):
c += b[i]
return c
def case2(n):
c = 0
for i in range(n):
for j in range(n):
for k in range(n):
c += i*j*k
return c
print(case1(10))
print(case2(10))
if __name__ == '__main__':
import timeit
print(timeit.timeit("case1(10)", setup="from __main__ import case1", number=10000))
print(timeit.timeit("case2(10)", setup="from __main__ import case2", number=10000))
В моем компьютере этот код работать в:
$ python3 code.py
91125
91125
2.435348572995281
1.6435037050105166
Таким образом, кажется, что 3 вложенные циклы являются более эффективными, потому что я провожу некоторое время создания массива b
в case1
. поэтому я не уверен, что я создаю этот массив наиболее эффективным способом, но, оставив это в стороне, действительно ли он окупает свертывающие циклы на один? Я использую Python здесь, но как насчет скомпилированных языков, таких как C++? Составляет ли компилятор в этом случае что-то для оптимизации одного цикла? Или, с другой стороны, делает ли компилятор некоторую оптимизацию, когда у вас несколько вложенных циклов?
Во втором примере первый является ручной сомнительна оптимизация решений код более сложный и сложный для оптимизации компилятором и процессором. Кроме того, он использует больше памяти. –
Почему не 'c = sum (i * j * k для i, j, k в itertools.product (диапазон (n), repeat = 3))'? – jonrsharpe
@jonrsharpe Я не могу этого сделать, потому что код, который я показал, просто для того, чтобы показать проблему. В реальном приложении я делаю в цикле другой материал (линейную алгебру), который использует результат этого массива. – aaragon