2 つまたは 3 つのループを使用して計算を実行する必要があるとします。直感的には、これを 1 つのループで行う方が効率的であると思うかもしれません。簡単な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
簡略化のために関数を使用しています)。つまり、すべてを 1 つのループにまとめると、サイズが 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
b
で配列を作成するのに時間がかかるため、3つのネストされたループの方が効率的であるようcase1
です。したがって、この配列を最も効率的な方法で作成しているかどうかはわかりませんが、それはさておき、ループを単一のものに折りたたむことは本当に報われますか? ここでは Python を使用していますが、C++ などのコンパイル済み言語はどうでしょうか。この場合、コンパイラは単一のループを最適化するために何かをしますか? あるいは、ネストされたループが複数ある場合、コンパイラは何らかの最適化を行いますか?