speed up prime calculations by 50%

add tool to check a prime as cmd arg
This commit is contained in:
code002lover 2024-07-19 17:15:18 +02:00
parent 49e24e5a61
commit 0fe3ffaa59
2 changed files with 36 additions and 8 deletions

View File

@ -24,15 +24,20 @@ pub mod prime_utils {
const ZERO: BigUint = BigUint::ZERO; const ZERO: BigUint = BigUint::ZERO;
let mut i = BigUint::one(); let mut i = BigUint::one();
let one = BigUint::one(); let one = BigUint::one();
let two = &one + &one;
let sqrtnum = number.sqrt() + &one; //fake ceil function if number % &two == ZERO {
return false;
}
let sqrtnum = number.sqrt() + one; //fake ceil function
loop { loop {
i += &one; i += &two; //we begin checking 3 and then continue with every second number as every even number is divisible by 2 and we already checked that
if number % &i == ZERO { if number % &i == ZERO {
return false; return false;
} }
if i == sqrtnum { if i >= sqrtnum {
return true; return true;
} }
} }

View File

@ -8,6 +8,7 @@ use crate::is_prime::prime_utils;
use num::{BigUint, One}; use num::{BigUint, One};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::{ use std::{
env::args,
io::Write, io::Write,
sync::{ sync::{
atomic::{AtomicU64, AtomicUsize}, atomic::{AtomicU64, AtomicUsize},
@ -47,8 +48,13 @@ fn try_set_thread_priority() {
} }
fn write_primes(primes: &[BigUint]) { fn write_primes(primes: &[BigUint]) {
let primes: Vec<String> = primes
.iter()
.map(std::string::ToString::to_string)
.collect();
let mut file = std::fs::File::create("primes.json").unwrap(); let mut file = std::fs::File::create("primes.json").unwrap();
file.write_all(serde_json::to_string(primes).unwrap().as_bytes()) file.write_all(serde_json::to_string(&primes).unwrap().as_bytes())
.unwrap(); .unwrap();
} }
@ -90,6 +96,19 @@ fn worker(
} }
fn main() { fn main() {
let mut args = args();
if args.len() == 2 {
use std::str::FromStr;
let prime = args.nth(1).unwrap();
println!(
"Number is prime: {}",
is_prime::prime_utils::is_prime(&BigUint::from_str(&prime).unwrap())
);
return;
}
let sys_time = SystemTime::now(); let sys_time = SystemTime::now();
let nthprime_approx: usize = to_usize(p(NF * 1.02)); let nthprime_approx: usize = to_usize(p(NF * 1.02));
@ -132,6 +151,7 @@ fn main() {
}); });
let mut primes = primearc.write().unwrap(); let mut primes = primearc.write().unwrap();
primes.sort_unstable();
#[allow(clippy::cast_possible_wrap)] #[allow(clippy::cast_possible_wrap)]
let removed: i32 = if primes.len() > NU { let removed: i32 = if primes.len() > NU {
@ -144,20 +164,23 @@ fn main() {
let added = NU - primes.len(); let added = NU - primes.len();
if primes.len() < NU { if primes.len() < NU {
static INC: once_cell::sync::Lazy<BigUint> = Lazy::new(BigUint::one); static INC: once_cell::sync::Lazy<BigUint> = Lazy::new(|| BigUint::from(2u8));
println!("[INFO] less primes than expected"); println!("[INFO] less primes than expected");
let mut number = BigUint::from(THREADS) * BigUint::from(workloads); let mut number = BigUint::from(THREADS) * BigUint::from(workloads);
if &number % &*INC == BigUint::ZERO {
number += BigUint::one();
}
loop { loop {
number += &*INC; number += &*INC;
if prime_utils::is_prime(&number) { if prime_utils::is_prime(&number) {
primes.push(number.clone()); primes.push(number.clone());
}
if primes.len() == NU { if primes.len() == NU {
break; break;
} }
} }
} }
}
let difference = sys_time.elapsed().unwrap(); let difference = sys_time.elapsed().unwrap();