Here is a simplified code of nested loop and some if-conditions regarding index-access to a list.
I noticed that the second code (# In separate loops) works twice faster than the first one (# In the same loops) in PyPy3 (ver. 7.3.1).
Both run in the almost same speed in CPython (3.8.4rc1).
What is the factor making the second one faster?
# In the same loop (slower)
import random
LIM = 10 ** 3
def main():
random.seed(0)
arr = [random.randint(0, 1) for _ in range(LIM * LIM)]
cnt = 0
for i in range(LIM):
for j in range(LIM):
if arr[i]:
cnt += 1
if arr[i * 2]:
cnt += 1
if arr[j]:
cnt += 1
if arr[j * 2]:
cnt += 1
if arr[i + LIM]:
cnt += 1
if arr[j + LIM]:
cnt += 1
if arr[i * j]:
cnt += 1
print(cnt)
if __name__ == "__main__":
main()
# In separate loops (faster)
import random
LIM = 10 ** 3
def main():
random.seed(0)
arr = [random.randint(0, 1) for _ in range(LIM * LIM)]
cnt = 0
for i in range(LIM):
for j in range(LIM):
if arr[i]:
cnt += 1
for i in range(LIM):
for j in range(LIM):
if arr[i * 2]:
cnt += 1
for i in range(LIM):
for j in range(LIM):
if arr[j]:
cnt += 1
for i in range(LIM):
for j in range(LIM):
if arr[j * 2]:
cnt += 1
for i in range(LIM):
for j in range(LIM):
if arr[i + LIM]:
cnt += 1
for i in range(LIM):
for j in range(LIM):
if arr[j + LIM]:
cnt += 1
for i in range(LIM):
for j in range(LIM):
if arr[i * j]:
cnt += 1
print(cnt)
if __name__ == "__main__":
main()