Sieve optimization
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
When people talk about sieve optimization, they usually mean making prime generation faster and leaner than the textbook Sieve of Eratosthenes implementation. The big gains come from avoiding unnecessary work: skip even numbers, start crossing out at p * p, and, for large limits, use segmented processing instead of one giant in-memory array.
Start with the Core Sieve Improvement
A naïve sieve marks multiples starting at 2 * p, even though smaller multiples were already handled by earlier primes. A better version starts at p * p.
Starting at p * p is not a tiny micro-optimization. It removes a large amount of redundant marking.
Skip Even Numbers
After handling 2, every remaining prime candidate is odd. Storing and checking only odd numbers cuts memory roughly in half and reduces loop work.
This version keeps the same mathematical result while wasting less space on values that can never be prime.
Use Segmented Sieve for Large Ranges
For very large limits, the main problem is memory locality. A segmented sieve processes the range in blocks, using smaller working arrays that fit cache better.
The rough approach is:
- generate primes up to
sqrt(limit) - process
[low, high]blocks - mark composites in each block using the base primes
Segmented sieve is the right move when the target range is big enough that one full boolean array becomes wasteful.
Think About Representation
Beyond algorithmic improvements, representation matters:
- Python
list[bool]is easy but not memory-optimal - bitsets are smaller
- cache-friendly arrays often outperform theoretically similar but fragmented structures
In low-level languages, bit-packed storage can be a major win. In higher-level languages, it is worth balancing implementation complexity against actual performance needs.
Benchmark the Right Bottleneck
Not every optimization helps equally for every limit. For smaller ranges, a plain p * p optimization may be enough. For larger ranges, segmented processing may dominate. Benchmark with realistic limits before making the code complicated.
A practical rule:
- small limit: simple sieve
- medium limit: odd-only sieve
- large limit: segmented sieve
The best version depends on your input sizes and memory constraints.
Common Pitfalls
- Starting composite marking at
2 * prepeats work that earlier primes already handled. - Keeping even numbers in the candidate array wastes memory and iterations.
- Using segmented sieve for tiny inputs can add complexity without meaningful benefit.
- Ignoring cache behavior can make a theoretically good implementation slower in practice.
- Benchmarking only once on a tiny range can lead to the wrong optimization choice for real workloads.
Summary
- Start composite marking at
p * p, not2 * p. - Skip even numbers after handling prime
2. - Use segmented sieve when the range is large enough that memory locality matters.
- Choose data representation based on actual performance constraints, not habit.
- Optimize in stages and benchmark against the input sizes you really care about.
Related reading
- Similar String algorithm
- similarity between two vectors representing star graphs
- Simple algorithm tutorials?
- Simple Popularity Algorithm
- Simple way to measure cell execution time in ipython notebook
- Simplifying expression trees
- Sigmoid output - can it be interpreted as probability?
- Simple Linear Regression in Python

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.