The number of cycles matters efficiency (interpreted as compiled languages?)

Let's say you have to do the calculation with 2 or even 3 cycles. Intuitively, one can say that it is more efficient to do this with a single cycle. I tried a simple Python example:

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))

This code run:

$ python3 code.py 
1000
1000
0.8281264099932741
1.04944919400441

So, an effective 1 cycle seems a bit more efficient. However, I have a slightly different scenario in my problem, since I need to use values ​​in an array (in the following example, I use a function rangeto simplify). That is, if I fold everything into one cycle, I will have to create an extended array from the values ​​of another array, the size of which is from 2 to 10 elements.

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))

On my computer, this code runs in:

$ python3 code.py 
91125
91125
2.435348572995281
1.6435037050105166

, , , - b case1. , , , , ? Python , , ++? - ? , , , ?

+4
2

,

b = [i * j * k for i, j, k in itertools.product(range(n), repeat=3)]

def case1(n, b):
    c = 0
    for i in range(len(b)):
        c += b[i]
    return c

timeit:

case1 : 0.965343249744
case2 : 2.28501694207
+2

, , , . numpy , , pypy JIT .

- dis, , , -, , , CPU. , .

Python -, , , . , . . , C, itertools.

C, : syscalls/mallocs() , , .

, , , , N - .

, , "c". , , .

. , , , , , , ...

def case3(n):
    c = 0
    for j in range(n):
        c += (j* n^2 *(n+1)^2))/4
    return c
+2

All Articles