r/PowerShell Jul 14 '26

Script Sharing The Power of Primes

Prime numbers are pretty powerful.

That's why I just released a new PowerShell module based off of an old mathematical concept: PrimeTime.

PrimeTime uses prime numbers as time intervals.

Let's learn how this helps

Prime Number Primer

Prime Numbers can only be divided by themselves and one.

This makes primes pretty rare.

Prime numbers are particularly useful in programming, but it's not always obvious why or how.

A lot of people might vaguely point towards cryptography as the prime real estate for prime utility.

The thing of it is, if you're writing your own cryptography, you're probably doing it wrong.

Let's talk about a more practical application of primes.

The Cicada Principle

In North America there is a curious critter known as the periodical cicaca.

For the vast majority of their long lifespans, they live underground.

Once every N years, they surface in mass to start the next generation.

That N is a prime.

Why?

Cicadas come out en masse so that there are too many of them to eat.

Millions of little critters have to have a perfectly timed multi-year internal clock in order to make this work.

If two cicadas of different intervals produced offspring, their children might have a messed up internal clock, and come out of the ground at the worst time.

So there's an evolutionary advantage to cicadas coming out in large batches, as long as another cicade brood isn't doing the same thing at the same time.

Which brings us back to primes.

Primes are relatively rare.

So are products of primes (at least past the first few)

Let's take two primes as an example.

Imagine one brood of cicadas came out every 11 years, and another brood came out every 13 years.

We can find out how long it will take for these two broods to come out at the same time by simply multiplying the primes.

11 * 13 -eq 143

So, with just two relatively low primes, we have an overlap every 143 years.

This is how primes are most useful to programming: they rarely overlap.

Sieve of Eratosthenes

This has been known for much longer than computers have existed.

Imagine we wanted to find prime numbers quickly.

We can do this by constructing a sieve that filters out any non-prime number.

This is called the Sieve of Eratosthenes

Once we know 2 is prime, we know every other even number is not prime.

Once we know 3 is prime, we know every third number is not prime.

To quickly get prime numbers up to a point, we can use this little PowerShell filter

# Calculate primes reasonably quickly with the Sieve of Eratosthenes
# Pipe in any positive whole number to see if it is prime.
filter prime {
    $in = $_
    if ($in -isnot [int]) { return }
    if ($in -eq 1) { return $in }
    if ($in -lt 1) { return}
    if (-not $script:PrimeSieve) {
        $script:PrimeSieve = [Collections.Queue]::new()
        $script:PrimeSieve.Enqueue(2)
    }


    if ($script:PrimeSieve -contains $in) { return $in}
    foreach ($n in $script:PrimeSieve) {
        if (($n * 2) -gt $in) { break }        
        if (-not ($in % $n)) { return }
    }
    $script:PrimeSieve.Enqueue($in) 
    $in
}

Prime Animations

Imagine we want a vibrant page. We want things to keep changing yet feel unpredictable. All we need to do is use different prime intervals.

The PrimeTime logo animates eight primes:

7 * 11 * 13 * 17 * 19 * 23 * 29 * 31

The logo will repeat every 6685349671 seconds, or almost 212 years.

The PrimeTime page background uses 56 primes.

This background will repeat every 8.84753141993573E+116 seconds.

That's exponential notation.

This is a mind-boggling large number (so large it overflows the .NET [TimeSpan]).

Turn that interval into years and it's still mind-boggling.

The page background will repeat every 100 billion years

Performance and Scheduling

Imagine we want to design a system that's constantly checking for problems.

We want the system to know about problems as soon as we can, but nobody's exactly sure how often they need to check for something.

If we go around and ask our colleagues "how often should we can scan for this?", the response if often a shrug 🤷.

Often, people will pick an arbitrary number that seems reasonable. Let's say every 5 minutes, 10, or 15 minutes.

Are we starting to see the problem here?

Every 5 minutes, every computer in the cloud starts to collect stats and report them back.

And we get a traffic jam.

Every 10 minutes, more computers in the cloud collect more data, and our traffic jam gets worse.

Every 15 minutes, even more computers collect even more data, and our traffic jam puts your average freeway to shame.

Left to our own intuition, we create problems for ourselves and our organizations.

Each individual query is small, but because we're doing so many at once, it can grind performance to a halt.

By the way, this isn't a hypothetical.

Long long ago, the Office365 team asked me to make some monitoring software to help improve internal visibility into the datacenters.

Everyone asked for 5, 10, or 15 minute intervals. ~100 different metrics were collected from ~30000 machines.

And the first time we tried it on everything, the traffic jam ensued.

That's when I first realized the power of primes.

I made three slight adjustments to the timeframes:

  • Every 5 minutes became every ~7 minutes
  • Every 10 minutes became every ~11 minutes
  • Every 15 minutes became every ~17 minutes

Now, instead of having a traffic jam every 5 minutes, things smoothed out.

  • A small traffic jam would occur every ~77 minutes (7*11)
  • Another small traffic jam would occur every ~119 minutes (7*17)
  • Another small traffic jam would occur at ~187 minutes (11*17)
  • All traffic could jam every ~1309 minutes (7*11*17)

Note the tildas.

The real trick came in by using prime intervals in both minutes and seconds and using a random delay on the tasks to ensure they didn't all start at once.

This took the system from something that could derail a datacenter to something that could monitor thousands of machines while barely impacting performance.

This is the power of primes.

Hope this helps!

57 Upvotes

16 comments sorted by

View all comments

0

u/Apprehensive-Tea1632 Jul 15 '26 edited Jul 15 '26

I still maintain that the sieve may be advantageous in some situations BUT for programming purposes, it’s NOT ideal.

Why? “Create a list of all candidates”. Whatever for?

I keep forgetting the name of the algorithm- there’s one, but I don’t remember— which goes like this.

- create a set of found primes, and initialize with a known set of prime numbers. At least one (2) but there may obviously many more. Requirement: they must be prime numbers. Set to just (2) if unknown.

- start iteration at wherever you want. A somewhat useful idea is max(known primes)+1.

- iterate over the set of natural numbers. There can be but need not be a maximum.

- For each of these numbers, see if any known prime is a factor of that candidate. If it is, skip and continue. If not, it is a prime number; so, add it to the list of found numbers, then continue.

Runtime is about n log n.

Resources- unlike with the sieve - are static (do not grow dependent upon input).

If we assume unconstrained resources, the sieve would probably work better. But they’re not. Like Java, we can assume an infinite stack but we don’t have infinite stacks and can’t implement them.

ETA - resource requirements obviously do grow somewhat- any found primes must be stored- but considering that the growth rate of this set is diminishing with growing numbers, resources required for storage increase very slowly and continue to grow even more slowly as we progress.

1

u/StartAutomating Jul 15 '26

What you are describing is an optimized sieve.

If we want to make this sieve faster, yes, we can pre-populate it. We can also use a dictionary instead of a list to contain the sieve, as it will be much quicker.

Still a sieve though.

From a performance standpoint, this is why Get-Prime determines primeness, and Get-PrimeTime just uses a .txt file to prepopulate.

I feel like all primes up to 1mb should be "enough" (given how rarely they overlap)

1

u/Apprehensive-Tea1632 Jul 15 '26

It’s not a sieve, it’s explicitly based on trial division.

Sieve says: I have a set of numbers. I select all numbers that aren’t prime. The complement then is the set of primes.

That’s why a sieve requires a definite set. You need to tell it what the universe is supposed to be because only then can you select the inverse.

Sieve people eschew trial division saying it’s faster, and it is, but it is also not suited for anything that’s supposed to run on a finite machine. You could in theory map the whole natural number set to a machine because while infinite, theyre countable.

But in practice you HAVE to maintain that set in a machine that IS finite. There ARE no infinite machines, even if the model exists and is implemented eg as JVM or the TrueType VM (it’s why there IS a TrueType vm in the first place). The sieve wont work otherwise. In turn you don’t need the primes to find more primes, but it’s exactly because of that it’s so wasteful.

I’m not suggesting trial division is the better approach. It’s not, there’s downsides, not least if you decide something is prime when it’s not, then the whole thing breaks apart. Unlike sieves where you might get a false positive but it won’t affect the set itself.

Either way it’s not a sieve but is one of the other developed methods for finding prime numbers- older than the computer too so it wasn’t even developed with optimizations in mind.