I got nerd-sniped from this LinkedIn post. On my computer, the R screenshot above ran in 1.564 minutes on my laptop for primes up to 1 million (Macbook Air M1 with arm64 binaries for Julia/R).
I had to give it a shot for comparison's sake. A basic 1:1 translation in Julia was 13.43 seconds (7x faster), and following the same conceptual algorithm (check for remainders up to sqrt(x)) but without as many intermediate allocations was 0.017 seconds (over 5,250x faster).
library(magrittr)
library(purrr)
library(dplyr)
library(lubridate)
primes_less_than <- 1000000
v.primes <- c(2,3)
start <- now()
walk((2:ceiling(primes_less_than/2)) * 2 -1,
function(x) {
if ((map_dbl(v.primes[v.primes <= sqrt(x)],
~ x %% .) %>% min) > 0) {
v.primes[length(v.primes) + 1] <<- x
}
}) %>%
suppressWarnings
print(now() - start)
function primes_up_to(k)
primes = [2,3]
for n in 3:2:k
remainders = n .% primes[primes .<= √(n)]
if minimum(remainders;init=1) > 0
push!(primes,n)
end
end
return primes
end
This follows the same idea (check for remainders up to sqrt(k)) but does not have as many intermediate allocations.
function primes_up_to(k)
primes = [2,3]
for n in 3:2:k
d = false
i = 1
while (~d) && (i < length(primes)) && (primes[i] <= sqrt(n))
if iszero(n % primes[i])
d = true
end
i += 1
end
if ~d
push!(primes,n)
end
end
return primes
end
By splitting into sub-functions, it becomes more readable (IMO) and facilitates some further optimizations.
function primes_up_to(k)
primes = [2,3]
for n in 3:2:k
if ~is_divisible(primes,n)
push!(primes,n)
end
end
return primes
end
function is_divisible(prime_list,n)
# integer sqrt keeps everything integers instead of comparing float with int
limit = isqrt(n)
for i ∈ eachindex(prime_list)
p = prime_list[i]
# short circuit and return if the conditionals are met
p > limit && return false
iszero(n % p) && return true
end
# we've exhausted the search and can return false
return false
end
These aren't directly comparable, as they have different algorithms. Two other options:
using Primes
primes(1_000_000)
using FastPrimeSieve
collect(FastPrimeSieve.SmallSieve(1_000_000))
@bkamins your version is indeed faster:
Main solution:
UInt32
version: