This blog has been rather neglected, but I’m getting towards the end of my batch at the Recurse Center in New York so I’m going to try updating it again.
My previous post showed a code-golfed prime sieve I wrote for fun in Haskell.
While trying to solve problem 35 from Project Euler (“How many circular primes are there under 1,000,000”), I found myself needing something like this again. Unfortunately, nubBy
has quite bad performance in this situation, so the one-line version is really inefficient. But, using Data.Vector
there turns out to be a much faster option:
This version takes the vector of numbers [2..1000000]
and sets all element that are multiples of any other number in the vector to 0, taking advantage of the fact that Vector has $O(1)$ indexing, rather than $O(n)$ for lists, and Data.Vector
’s batch update operator //
so updates can be staged and done all at once rather than done individually. This is not surprisingly much faster than recursively filtering a list as is done with nubBy
. There’s still some redundancy in how isMult
generates updates, plus some less-than-ideal fiddling with indexes, so there’s a lot of space for improvement, but using this instead of the list-based version took the full solution from unusably slow to running in ~7 seconds.