Created
November 30, 2013 08:45
-
-
Save Rhomboid/7716724 to your computer and use it in GitHub Desktop.
Python number sieve performance comparison
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # http://projecteuler.net/problem=7 (should print 104743) | |
| from operator import itemgetter | |
| from timeit import repeat | |
| def ver1(n): | |
| '''Original, baseline version that uses a dict''' | |
| eratosthenes = dict.fromkeys(range(2, n), True) | |
| for i in range(2, n): | |
| if eratosthenes[i]: | |
| for j in range(i**2, n, i): | |
| eratosthenes[j] = False | |
| prime_list = eratosthenes.items() | |
| filtered_prime_list = [] | |
| for tuple in prime_list: | |
| if tuple[1]: | |
| filtered_prime_list.append(tuple[0]) | |
| return filtered_prime_list | |
| def ver2(n): | |
| '''Use a list instead of a dict, and build primes list as you go''' | |
| sieve = [True] * n | |
| primes = [] | |
| for i in range(2, n): | |
| if sieve[i]: | |
| primes.append(i) | |
| sieve[i * 2::i] = (False,) * ((n - i - 1) // i) | |
| return primes | |
| def ver3(n): | |
| '''Use list.index to find next prime''' | |
| sieve = [True] * n | |
| primes = [] | |
| i = 1 | |
| while True: | |
| try: | |
| i = sieve.index(True, i + 1) | |
| except ValueError: | |
| return primes | |
| primes.append(i) | |
| sieve[i * 2::i] = (False,) * ((n - i - 1) // i) | |
| def ver4(n): | |
| '''Use bytearray.index to find next prime''' | |
| sieve = bytearray(b'1' * n) | |
| primes = [] | |
| i = 1 | |
| while True: | |
| try: | |
| i = sieve.index(b'1', i + 1) | |
| except ValueError: | |
| return primes | |
| primes.append(i) | |
| sieve[i * 2::i] = b'0' * ((n - i - 1) // i) | |
| def ver5(n): | |
| '''Use list.index and only store odd numbers''' | |
| n //= 2 | |
| sieve = [True] * n | |
| primes = [2] | |
| i = 0 | |
| while True: | |
| try: | |
| i = sieve.index(True, i + 1) | |
| except ValueError: | |
| return primes | |
| p = 2 * i + 1 | |
| primes.append(p) | |
| sieve[i + p::p] = (False,) * ((n - i - 1) // p) | |
| def ver6(n): | |
| '''Use bytearray.index and only store odd numbers''' | |
| n //= 2 | |
| sieve = bytearray(b'1' * n) | |
| primes = [2] | |
| i = 0 | |
| while True: | |
| try: | |
| i = sieve.index(b'1', i + 1) | |
| except ValueError: | |
| return primes | |
| p = 2 * i + 1 | |
| primes.append(p) | |
| sieve[i + p::p] = b'0' * ((n - i - 1) // p) | |
| repcnt = 25 | |
| funcs = [{'name': name, 'func': func} for name, func in globals().items() if name.startswith('ver')] | |
| for f in funcs: | |
| primes = f['func'](105000) | |
| assert primes[10000] == 104743 and len(primes) == 10024 | |
| f['elap'] = min(repeat('{}(105000)'.format(f['name']), 'from __main__ import {}'.format(f['name']), repeat=5, number=repcnt)) / repcnt | |
| slowest = max(f['elap'] for f in funcs) | |
| print('{:10} {:65} {:>8} {:>8}'.format('function', 'description', 'elapsed', 'speedup')) | |
| for f in sorted(funcs, key=itemgetter('elap'), reverse=True): | |
| print('{:10} {:65} {:8.6f} {:7.2f}x'.format(f['name'], f['func'].__doc__, f['elap'], slowest / f['elap'])) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # python 3.3.3, Windows x86 | |
| function description elapsed speedup | |
| ver1 Original, baseline version that uses a dict 0.047903 1.00x | |
| ver6 Use bytearray.index and only store odd numbers 0.017016 2.82x | |
| ver4 Use bytearray.index to find next prime 0.016434 2.91x | |
| ver2 Use a list instead of a dict, and build primes list as you go 0.014152 3.38x | |
| ver3 Use list.index to find next prime 0.012595 3.80x | |
| ver5 Use list.index and only store odd numbers 0.010860 4.41x | |
| # python 2.7.5, Windows x86 | |
| function description elapsed speedup | |
| ver1 Original, baseline version that uses a dict 0.056467 1.00x | |
| ver2 Use a list instead of a dict, and build primes list as you go 0.012120 4.66x | |
| ver3 Use list.index to find next prime 0.010797 5.23x | |
| ver6 Use bytearray.index and only store odd numbers 0.010267 5.50x | |
| ver5 Use list.index and only store odd numbers 0.009742 5.80x | |
| ver4 Use bytearray.index to find next prime 0.009481 5.96x | |
| # python 3.3.3, Windows x86_64 | |
| function description elapsed speedup | |
| ver1 Original, baseline version that uses a dict 0.048371 1.00x | |
| ver6 Use bytearray.index and only store odd numbers 0.019052 2.54x | |
| ver4 Use bytearray.index to find next prime 0.018135 2.67x | |
| ver2 Use a list instead of a dict, and build primes list as you go 0.012787 3.78x | |
| ver3 Use list.index to find next prime 0.012775 3.79x | |
| ver5 Use list.index and only store odd numbers 0.010947 4.42x | |
| # python 2.7.5, Windows x86_64 | |
| function description elapsed speedup | |
| ver1 Original, baseline version that uses a dict 0.061123 1.00x | |
| ver2 Use a list instead of a dict, and build primes list as you go 0.011829 5.17x | |
| ver3 Use list.index to find next prime 0.011191 5.46x | |
| ver5 Use list.index and only store odd numbers 0.008613 7.10x | |
| ver6 Use bytearray.index and only store odd numbers 0.008473 7.21x | |
| ver4 Use bytearray.index to find next prime 0.008438 7.24x | |
| # python 2.7.2, Linux x86_64 | |
| function description elapsed speedup | |
| ver1 Original, baseline version that uses a dict 0.048277 1.00x | |
| ver2 Use a list instead of a dict, and build primes list as you go 0.010998 4.39x | |
| ver3 Use list.index to find next prime 0.008768 5.51x | |
| ver6 Use bytearray.index and only store odd numbers 0.008062 5.99x | |
| ver4 Use bytearray.index to find next prime 0.007823 6.17x | |
| ver5 Use list.index and only store odd numbers 0.007440 6.49x | |
| # python 3.2.2, Linux x86_64 | |
| function description elapsed speedup | |
| ver1 Original, baseline version that uses a dict 0.033647 1.00x | |
| ver6 Use bytearray.index and only store odd numbers 0.011535 2.92x | |
| ver4 Use bytearray.index to find next prime 0.011267 2.99x | |
| ver2 Use a list instead of a dict, and build primes list as you go 0.008681 3.88x | |
| ver3 Use list.index to find next prime 0.008213 4.10x | |
| ver5 Use list.index and only store odd numbers 0.006904 4.87x | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment