finds primes using Eratosthenes sieving algorithm
Project description
primesgen is a collection of implementations of the Eratosthenes Sieve algorithm, leveraging numpy
all timing results displayed are from a 2.3 GHz 8-Core Intel Core i9/16 GB 2400 MHz DDR4 machine (Darwin)
config
config houses some platform dependent constant used internally (primarily for the factory methods and segmentation), to use:
from primesgen.config import multiples_cutoff, multiples_block_size, primes_block_size, primes_cutoff, segment_size
the L1D cache size determination OS dependent and also is in config.py:
def get() -> int:
os = platform.system()
if os == 'Darwin':
return _CacheSize._get_darwin()
elif os == 'Linux':
return _CacheSize._untested_get_linux()
raise NotImplementedError(f'not implemented for your operating system: {os}')
implementations
the 2 implementations can either return a list of primes (all in an array), or a generator
primesgen.Erastothenes
fastest, and it’s quite simple. Here is a quick example with timing:
from primesgen.sieve import Eratosthenes
max_val = 1_000_000_000
as_list = Eratosthenes().primes(max_val)
finds all 50,847,533 primes < 1,000,000,000 in 8.9 seconds
primesgen.SegmentedEratosthenes
segments the sieve which allows processing larger numbers than the other implementations
multiples and primes
the segmented algorithm accumulates prime values and segment multiples (1 for each prime < sqrt(max value)) for each segment processed
these will ultimately run out of memory
if you don’t care to manage the details, just use the factory methods
from primesgen.multiples import Multiples
from primesgen.primes import Primes
primes = Primes.factory()
multiples = Multiples.factory()
you can also specify in memory types
from primesgen.multiples import MultiplesInMem
from primesgen.primes import PrimesInMem
max_val = 1_000_000_000
primes = PrimesInMem()
multiples = MultiplesInMem(max_val)
you can also specify backed by disk types, which only keep a portion of data on the data in memory with the rest backed by files (files are in /var/tmp/primesgen*, with previous run(s) deleted each time)
from primesgen.config import multiples_block_size, primes_block_size
from primesgen.multiples import MultiplesOnDisk
from primesgen.primes import PrimesOnDisk
max_val = 1_000_000_000
primes = PrimesOnDisk(primes_block_size)
multiples = MultiplesOnDisk(max_val, multiples_block_size)
finally, you can use a type for Primes that broadcasts the primes to a queue
you still need to decide what kind of multiples to use (here I chose OnDisk)
import queue
from primesgen.config import multiples_block_size
from primesgen.multiples import MultiplesOnDisk
from primesgen.primes import PrimesToQueue
max_val = 1_000_000_000
primes_queue = queue.Queue(maxsize=0)
primes = PrimesToQueue(primes_queue)
multiples = MultiplesOnDisk(max_val, multiples_block_size)
full example
using the PrimesToQueue and MultiplesOnDisk types (with a custom queue consumer that prints to screen)
import queue
import time
from threading import Thread
from primesgen.config import segment_size, multiples_block_size
from primesgen.multiples import Multiples, MultiplesOnDisk
from primesgen.primes import Primes
from primesgen.sieve import SegmentedEratosthenes
def example_queue_consumer(in_queue: queue.Queue[int]) -> None:
# this is an example of someone consuming the primes if a queue is provided
print_count = 10_000_000
count = 0
partial_count = 0
while True:
prime = in_queue.get()
in_queue.task_done()
if prime is not None:
count += 1
partial_count += 1
if partial_count >= print_count or prime is None:
print(f'\tfound {count:,} primes thus far')
partial_count = 0
if prime is None:
break
max_val = 1_000_000_000
primes_queue = queue.Queue(maxsize=0)
primes = Primes.factory(in_queue=primes_queue)
multiples = MultiplesOnDisk(max_val, multiples_block_size)
sieve = SegmentedEratosthenes(segment_size, primes, multiples)
print_thread = Thread(target=example_queue_consumer, args=(primes_queue,))
sieve_thread = Thread(target=sieve.primes, args=(max_val,))
start = time.time()
sieve_thread.start()
print_thread.start()
sieve_thread.join()
duration = time.time() - start
print_thread.join()
<consumer> received 10,000,000 primes thus far (34.957 seconds)
<consumer> received 20,000,000 primes thus far (75.803 seconds)
<consumer> received 30,000,000 primes thus far (118.922 seconds)
<consumer> received 40,000,000 primes thus far (155.940 seconds)
<consumer> received 50,000,000 primes thus far (185.011 seconds)
<consumer> received 50,847,533 primes thus far (185.791 seconds)
finds/broadcasts all 50,847,533 primes <= 1,000,000,000 in 184.0 seconds
example: full control
using the PrimesOnDisk and MultiplesOnDisk types, with all the block and segment sizes as vars you can tweak
from primesgen.multiples import MultiplesOnDisk
from primesgen.primes import PrimesOnDisk
from primesgen.sieve import SegmentedEratosthenes
max_val = 100_000_000
primes_block_size = 100_000
mulitples_block_size = 50_000
segment_max_size = 32_000
primes = PrimesOnDisk(primes_block_size)
multiples = MultiplesOnDisk(max_val, mulitples_block_size)
sieve = SegmentedEratosthenes(segment_max_size, primes, multiples)
primes_list = sieve.primes(max_val)
Tests
pytest results should look like
=== test session starts ====
configfile: pyproject.toml
collected 11 items
tests/test_mulitples.py ..
tests/test_primes.py ...
tests/test_sieve.py ......
=== 11 passed in 21.05s ====
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file primesgen-1.0.5.tar.gz.
File metadata
- Download URL: primesgen-1.0.5.tar.gz
- Upload date:
- Size: 9.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95f1bbc3fb4da0e83fd31db73364e19c5ceafa5164d22c8796e54236891c1734
|
|
| MD5 |
4561de210c79b74759bcad6f51bd3487
|
|
| BLAKE2b-256 |
4ee8227532c5616e49f19bb66db245684097bcf8b9dcf2be95a5a9d62cbfc0fc
|
File details
Details for the file primesgen-1.0.5-py3-none-any.whl.
File metadata
- Download URL: primesgen-1.0.5-py3-none-any.whl
- Upload date:
- Size: 8.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb8d5a45a328c766bf6067d656a1ebf4bf1e76a40c01d10070507f08d25a9371
|
|
| MD5 |
544b5e6d0f88163901f080c675d9cef8
|
|
| BLAKE2b-256 |
58307ddf883bfc47b6ce42b87fa9eb3e205ffe789dc76a842d611e2f51a13de3
|