From 0dd7ea4e7cf470beaf2eb50b834b3cd5bb0e7ffe Mon Sep 17 00:00:00 2001 From: Mystikfluu Date: Thu, 2 Mar 2023 20:53:13 +0100 Subject: [PATCH] optimize --- .gitignore | 3 +- Cargo.toml | 6 ++-- src/is_prime.rs | 47 ++++++++++--------------- src/main.rs | 92 ++++++++++++++++++++++++++++--------------------- 4 files changed, 76 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index ca3108f..0bbc6ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -report.json \ No newline at end of file +report.json +primes.json \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 805d545..007a68e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,11 +6,11 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -num-bigint = { default-features = false, version = "0.4.3" } -thread-priority = "0.10.0" +num-bigint = { default-features = false, version = "0" } +thread-priority = "0" [profile.release] lto = true # Enable link-time optimization codegen-units = 1 # Reduce number of codegen units to increase optimizations panic = 'abort' # Abort on panic -# strip = true # Strip symbols from binary; remove pdb \ No newline at end of file +strip = true # Strip symbols from binary; remove pdb \ No newline at end of file diff --git a/src/is_prime.rs b/src/is_prime.rs index 1fa15bf..6658f0d 100644 --- a/src/is_prime.rs +++ b/src/is_prime.rs @@ -30,34 +30,26 @@ pub mod prime_utils { let zero = BigUint::from(0u8); let sqrtnum = number.sqrt()+&one; //fake ceil function - let mut is_prime = true; - match g_primes.iter().max() { - Some(max_value) => { - if max_value > &sqrtnum { - for prime in g_primes { - if prime<&sqrtnum { - if number%prime == zero { - return false; - } - } + if let Some(max_value) = g_primes.iter().max() { + if max_value > &sqrtnum { + for prime in g_primes { + if prime<&sqrtnum && number%prime == zero { + return false; } - } - }, - None => {} - }; - - loop { - i = i + &one; - if number%&i == zero { - is_prime = false; - break; - } - if i == sqrtnum { - break; + } + } + } + + loop { + i += &one; + if number%&i == zero { + return false; + } + if i == sqrtnum { + return true; } } - return is_prime; } // 4 12 194 @@ -66,11 +58,8 @@ pub mod prime_utils { for _i in 2..a { last = (last.pow(2)-&two)%number; } - if last == BigUint::from(0u8) { - true - } else { - false - } + + last == BigUint::from(0u8) } } diff --git a/src/main.rs b/src/main.rs index 41b0606..ccbc32d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ +#![warn(clippy::pedantic)] + pub mod is_prime; -use std::{time::SystemTime,thread}; +use std::{time::SystemTime,thread, io::Write}; use num_bigint::BigUint; use crate::is_prime::prime_utils; use thread_priority::{set_current_thread_priority,ThreadPriority}; @@ -44,9 +46,11 @@ fn main() { let sys_time = SystemTime::now(); - let n:f64 = 1_000_000f64; - let nthprime_approx = p(n*1.02) as u128; - const THREADS: u128 = 12; + const N:i64 = 100_000; + const NU:usize = N as usize; + let nf:f64 = 100_000f64; + let nthprime_approx:usize = p(nf*1.02).ceil() as usize; + const THREADS: usize = 12; let workloads = nthprime_approx/THREADS; let primecache: Vec = vec![]; @@ -55,14 +59,15 @@ fn main() { let mut joins = vec![]; for i in 0..THREADS { let arcclone = primearc.clone(); - let tprimes = thread::spawn(move || { + let handle = thread::spawn(move || { if set_current_thread_priority(ThreadPriority::Max).is_err() { eprintln!("failed to set thread priority to max"); } - let one_thousand = &BigUint::from(1_000u16); - let one_hundred = &BigUint::from(100u8); + const SPLITTER: u128 = 10000u128; + let one_thousand = &BigUint::from(SPLITTER*10); + let one_hundred = &BigUint::from(SPLITTER); let ten = &BigUint::from(10u8); @@ -74,14 +79,18 @@ fn main() { let max = BigUint::from(i+1)*work_uint; let mut primecache = vec![]; loop { - number = number + &inc; + number += &inc; - if prime_utils::is_prime(&number,&mut primecache) { + if prime_utils::is_prime(&number,&primecache) { primecache.push(number.clone()); //println!("Found a prime {} {}",number, primecache.len()); } if (&number * one_thousand)/&max/ten == &number/&max*one_hundred { + let tried_getting = SystemTime::now(); let mut new_primecache = arcclone.lock().unwrap(); + if SystemTime::now().duration_since(tried_getting).unwrap().as_millis() > 50 { + eprintln!("Waited 0.05+ seconds for lock!"); + } new_primecache.append(&mut primecache); new_primecache.sort(); new_primecache.dedup(); @@ -96,51 +105,43 @@ fn main() { let mut new_primecache = arcclone.lock().unwrap(); new_primecache.append(&mut primecache); - drop(primecache); new_primecache.sort(); new_primecache.dedup(); - - true }); - joins.push(tprimes); + joins.push(handle); } - loop { - let mut njoins = vec![]; - for join in joins { - if join.is_finished() { - join.join().unwrap(); - } else { - njoins.push(join); - } - } - joins = njoins; - if joins.len()==0 { - break; - } + for handle in joins { + handle.join().unwrap(); } let mut primes = primearc.lock().unwrap().to_vec(); - let removed = (primes.len()-n as usize).clamp(0, primes.len()); - if removed != 0 { - println!("removing {removed} primes"); - for _ in 0..removed { + let removed:i32 = if primes.len() > NU { + let mut rem = 0; + loop { + if primes.len() <= NU { + break; + } + rem+=1; primes.pop(); } - } + rem + } else { + 0 + }; - let added = n as usize-primes.len(); - if primes.len() < n as usize { + let added = NU-primes.len(); + if primes.len() < NU { println!("Less primes than expected!"); let mut number = BigUint::from(THREADS)*BigUint::from(workloads); let inc = BigUint::from(1u8); loop { - number = number + &inc; + number += &inc; if prime_utils::is_prime(&number, &primes) { primes.push(number.clone()); } - if primes.len() == n as usize { + if primes.len() == NU { break; } } @@ -150,12 +151,25 @@ fn main() { let difference = new_sys_time.duration_since(sys_time) .expect("Clock may have gone backwards"); - println!("{:?}", primes); + assert_eq!(primes.len(),NU); - println!("prime count: {}, expected: {}, primes added: {} | {}%, removed: {}",primes.len(),n,added,(added as f64)/primes.len() as f64*100.0, removed); - println!("last prime approx: {}",nthprime_approx); + println!("primes added: {} | % added: {}% | removed: {}",added,(added as f64)/primes.len() as f64*100.0,removed); + + println!("time: {difference:?}"); + + println!("writing primes..."); + + let mut file = std::fs::File::create("primes.json").unwrap(); + file.write_all(b"[").unwrap(); + let mut it = primes.iter().peekable(); + while let Some(prime) = it.next() { + file.write_all(prime.to_string().as_bytes()).unwrap(); + if it.peek().is_some() { + file.write_all(b",").unwrap(); + } + } + file.write_all(b"]").unwrap(); - println!("And that's time: {difference:?}"); }