diff --git a/Cargo.toml b/Cargo.toml index 18e347b..9b9b39e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ edition = "2021" num-bigint = { default-features = false, version = "0.4.3" } [profile.release] -opt-level = 'z' # Optimize for size lto = true # Enable link-time optimization codegen-units = 1 # Reduce number of codegen units to increase optimizations panic = 'abort' # Abort on panic diff --git a/src/main.rs b/src/main.rs index 0e84896..9c2648a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,22 @@ pub mod is_prime; -use std::{time::SystemTime,sync::mpsc,thread}; +use std::{time::SystemTime,thread}; use num_bigint::BigUint; use crate::is_prime::is_prime::is_prime; +fn p(n: f64) -> f64 { + let ln_n = n.ln(); + let ln_ln_n = ln_n.ln(); + let ln_ln_ln_n = ln_ln_n.ln(); + + n * ( + ln_n + ln_ln_n - 1.0 + + (ln_ln_ln_n - 2.0) / ln_n + - ((ln_ln_n).powi(2) - 6.0 * ln_ln_n + 11.0) / (2.0 * 2.0f64.log2() * ln_n) + + ((ln_ln_n / ln_n).powi(3)) * (1.0 / ln_n) + ) +} + fn main() { /* @@ -32,15 +45,69 @@ fn main() { // tx.send(val).unwrap(); // }); // TODO: multithreading + let n:f64 = 1_000_000f64; + let nthprime_approx = p(n*1.01) as u128; + const THREADS: u128 = 12; + let workloads = nthprime_approx/THREADS; - let mut number = BigUint::from(0u8); - let inc = BigUint::from(1u8); let mut primes: Vec = vec![]; + let mut joins = vec![]; + for i in 0..THREADS { + let tprimes = thread::spawn(move || { + let mut lprimes = vec![]; + let mut number = BigUint::from(i)*BigUint::from(workloads); + let inc = BigUint::from(1u8); + + let max = BigUint::from(i+1)*BigUint::from(workloads); + + loop { + number = number + inc.clone(); + if is_prime(number.clone()) { + lprimes.push(number.clone()); + } + if number == max { + break; + } + } + lprimes + }); + joins.push(tprimes); + } + loop { - number = number + inc.clone(); - if is_prime(number.clone()) { - primes.push(number.clone()); - if primes.len() >= 1_000_000 { + let mut njoins = vec![]; + for join in joins { + if join.is_finished() { + let tp = join.join(); + if let Ok(mut tprimes) = tp { + primes.append(&mut tprimes); + } + } else { + njoins.push(join); + } + } + joins = njoins; + if joins.len()==0 { + break; + } + } + let removed = (primes.len()-n as usize).clamp(0, n as usize); + if primes.len() > n as usize { + for _ in 0..removed { + primes.pop(); + } + } + + let added = (n as usize-primes.len()).clamp(0, n as usize); + if primes.len() < n as usize { + let mut number = BigUint::from(THREADS+1)*BigUint::from(workloads); + let inc = BigUint::from(1u8); + loop { + number = number + inc.clone(); + if is_prime(number.clone()) { + primes.push(number.clone()); + } + if primes.len() == n as usize { break; } } @@ -52,6 +119,9 @@ fn main() { println!("{:?}", primes); + println!("prime count: {}, expected: {}, primes removed: {} | {}%, primes added: {} | {}%",primes.len(),n,removed,(removed as f64)/primes.len() as f64*100.0,added,(added as f64)/primes.len() as f64*100.0); + println!("last prime approx: {}",nthprime_approx); + println!("And that's time: {difference:?}");