-
Notifications
You must be signed in to change notification settings - Fork 1
Home
This library contains 3 generators to choose from, based on your use case. Also check the benchmark performance figures.
-
Default
primeGenenerator()- produces primes from 2 untilmaxPrime = 9_007_199_254_740_881, which is hypothetically reachable, after running for 10+ years, so it can be considered infinite. This is the most efficient method in terms of memory and CPU usage, and can produce the first million primes in under half-second. -
Fast
primeGenerator({boost: N})- produces up toNprimes. It boosts performance 10x times over the default method, by pre-allocating a memory buffer for the calculation. However, this brings memory penalty, and soNis capped at 100mln primes, which at peak will use about 127MB of RAM. -
Offset
primeGenerator({start: S})- produces all primes betweenS(inclusive) andmaxPrime. It has the same memory + CPU efficiency as the default method, and is the best at finding primes above a certain range.
Note that you cannot combine start and boost options, because the fast method can only produce primes from the beginning, while the offset method cannot buffer its calculation.
If you need to store a relatively large number of primes in memory, for quick access, and concerned about memory usage, this library has a function cachePrimes to help with that. It relies on the fact that the first 23_163_298 primes all have gaps between them <= 255, so they all can be compressed into a 1-byte list of gaps, which is what this function does. This way, you end up using 8 times less memory.
import {cachePrimes, maxCacheSize} from 'prime-lib';
// maxCacheSize = 23_163_298
const cache = cachePrimes(10); // returns a read-only iterator
const list = [...cache]; //=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
for(const prime of cache) {
// for-of iteration is faster than index-based iteration
}
for(let i = 0;i < cache.length;i ++) {
// access by index uses segments, for faster calculation
const prime = cache[i];
}Performance discrepancy between for-of iteration and index-based iteration of cache grows with the size of the cache.
At its peak, with the cache size of maxCacheSize, indexed-based iteration takes about 665ms, while for-of iteration will
finish in 58ms, i.e. 11.5 times difference. For cache size of 1 million, the difference is about 6 times; for 100k - about 50%,
and even less for a smaller cache.
The returned cache object is RXJS-friendly:
import {from} from 'rxjs';
import {cachePrimes} from 'prime-lib';
const cache = cachePrimes(10);
from(cache).subscribe(prime => {
// 2, 3, 5, 7, 11, 13, 17, 19, 23, 29
});This library includes 3 stop-iterators - stopOnValue, stopOnCount, and generic stopWhen, to help limit generators. These are mainly for regular JavaScript and TypeScript clients, as RXJS provides its own operators for this.
However, you can combine them with RXJS, if you like - see the example below.
Let's produce all prime numbers between 100 and 200:
import {from} from 'rxjs';
import {generatePrimes, stopOnValue} from 'prime-lib';
const iterator = stopOnValue(generatePrimes({start: 100}), 200);
from(iterator)
.subscribe(prime => {
// 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
// 157, 163, 167, 173, 179, 181, 191, 193, 197, 199
});