As Oscar's answer indicates, your algorithm repeats a lot of work. To see how much processing will be saved in another algorithm, consider the following modified version of the mark() and isprime() functions, which track how many times the function has been called, and the total number of iterations of the loop:
calls, count = 0, 0 def mark(sieve, x): global calls, count calls += 1 for i in xrange(x+x, len(sieve), x): count += 1 sieve[i] = False
After starting the first code with this new function, we can see that mark() is called 223 times, for a total of 4,489,006 (~ 4.5 million) iterations in a for loop.
calls, count = 0 def isprime(n): global calls, count calls += 1 for x in xrange(3, int(n**0.5)+1): count += 1 if n % x == 0: return False return True
If we make a similar change for your code, we will see that isprime() is called 1,000,000 (1 million) times with 177,492,735 (~ 177.5 million) iterations of the for loop.
Counting function calls and loop iterations are not always a convincing way to determine why an algorithm runs faster, but usually fewer steps == less time, and obviously your code can use some optimization to reduce the number of steps.
source share