简体   繁体   中英

Why does the second code segment run so much faster than the first?

I have two different takes on the same function:

def is_prime(number):
    for denominator in range(2, number):
        if denominator ** 2 > number:
            return True
        if number % denominator == 0:
            return False
    return True

And

def is_prime(number):
    denominator = 2
    while denominator ** 2 <= number:
        if number % denominator == 0:
            return False
        denominator += 1
    return True

The first block of code, when used to test the first 10**5 numbers takes ~30 seconds to complete, the second takes around 350ms. Both come to the same answer for all test cases.
Why is there such a large difference in performance?

Note: This quirk fell out of testing performance of a ctypes import, I am aware that range(math.sqrt(number)) is faster, and that we can use Fermat's little theorem to make it faster still.

While it's true that snippet 1 has more instructions to execute, two if statements will only double your execution time for those if statements (I'm using only as a relative term here). The majority of your speed is lost in the for loop:

python -m timeit -s 'i=0' 'for x in range(1000): i+=1' 
10000 loops, best of 3: 46.4 usec per loop

python -m timeit -s 'i=0' 'while i<1000: i+=1' 
10000 loops, best of 3: 0.0299 usec per loop

You are losing multiple orders of magnitude in the for loop, so the if statement is relatively inconsequential:

python -m timeit -s 'x=1; y=4' 'x<y'
10000000 loops, best of 3: 0.0256 usec per loop

However, I will point out that this is the case for python3's range and python2's xrange . If you are using python2's range , as @jdowner pointed out, you will be generating the entire list of numbers ahead of time

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM