optimize
This commit is contained in:
parent
5950d10d98
commit
0dd7ea4e7c
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
report.json
|
report.json
|
||||||
|
primes.json
|
@ -6,11 +6,11 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num-bigint = { default-features = false, version = "0.4.3" }
|
num-bigint = { default-features = false, version = "0" }
|
||||||
thread-priority = "0.10.0"
|
thread-priority = "0"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true # Enable link-time optimization
|
lto = true # Enable link-time optimization
|
||||||
codegen-units = 1 # Reduce number of codegen units to increase optimizations
|
codegen-units = 1 # Reduce number of codegen units to increase optimizations
|
||||||
panic = 'abort' # Abort on panic
|
panic = 'abort' # Abort on panic
|
||||||
# strip = true # Strip symbols from binary; remove pdb
|
strip = true # Strip symbols from binary; remove pdb
|
@ -30,34 +30,26 @@ pub mod prime_utils {
|
|||||||
let zero = BigUint::from(0u8);
|
let zero = BigUint::from(0u8);
|
||||||
|
|
||||||
let sqrtnum = number.sqrt()+&one; //fake ceil function
|
let sqrtnum = number.sqrt()+&one; //fake ceil function
|
||||||
let mut is_prime = true;
|
|
||||||
|
|
||||||
match g_primes.iter().max() {
|
if let Some(max_value) = g_primes.iter().max() {
|
||||||
Some(max_value) => {
|
if max_value > &sqrtnum {
|
||||||
if max_value > &sqrtnum {
|
for prime in g_primes {
|
||||||
for prime in g_primes {
|
if prime<&sqrtnum && number%prime == zero {
|
||||||
if prime<&sqrtnum {
|
return false;
|
||||||
if number%prime == zero {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => {}
|
}
|
||||||
};
|
|
||||||
|
loop {
|
||||||
loop {
|
i += &one;
|
||||||
i = i + &one;
|
if number%&i == zero {
|
||||||
if number%&i == zero {
|
return false;
|
||||||
is_prime = false;
|
}
|
||||||
break;
|
if i == sqrtnum {
|
||||||
}
|
return true;
|
||||||
if i == sqrtnum {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return is_prime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4 12 194
|
// 4 12 194
|
||||||
@ -66,11 +58,8 @@ pub mod prime_utils {
|
|||||||
for _i in 2..a {
|
for _i in 2..a {
|
||||||
last = (last.pow(2)-&two)%number;
|
last = (last.pow(2)-&two)%number;
|
||||||
}
|
}
|
||||||
if last == BigUint::from(0u8) {
|
|
||||||
true
|
last == BigUint::from(0u8)
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
92
src/main.rs
92
src/main.rs
@ -1,6 +1,8 @@
|
|||||||
|
#![warn(clippy::pedantic)]
|
||||||
|
|
||||||
pub mod is_prime;
|
pub mod is_prime;
|
||||||
|
|
||||||
use std::{time::SystemTime,thread};
|
use std::{time::SystemTime,thread, io::Write};
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
use crate::is_prime::prime_utils;
|
use crate::is_prime::prime_utils;
|
||||||
use thread_priority::{set_current_thread_priority,ThreadPriority};
|
use thread_priority::{set_current_thread_priority,ThreadPriority};
|
||||||
@ -44,9 +46,11 @@ fn main() {
|
|||||||
|
|
||||||
let sys_time = SystemTime::now();
|
let sys_time = SystemTime::now();
|
||||||
|
|
||||||
let n:f64 = 1_000_000f64;
|
const N:i64 = 100_000;
|
||||||
let nthprime_approx = p(n*1.02) as u128;
|
const NU:usize = N as usize;
|
||||||
const THREADS: u128 = 12;
|
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 workloads = nthprime_approx/THREADS;
|
||||||
|
|
||||||
let primecache: Vec<BigUint> = vec![];
|
let primecache: Vec<BigUint> = vec![];
|
||||||
@ -55,14 +59,15 @@ fn main() {
|
|||||||
let mut joins = vec![];
|
let mut joins = vec![];
|
||||||
for i in 0..THREADS {
|
for i in 0..THREADS {
|
||||||
let arcclone = primearc.clone();
|
let arcclone = primearc.clone();
|
||||||
let tprimes = thread::spawn(move || {
|
let handle = thread::spawn(move || {
|
||||||
|
|
||||||
if set_current_thread_priority(ThreadPriority::Max).is_err() {
|
if set_current_thread_priority(ThreadPriority::Max).is_err() {
|
||||||
eprintln!("failed to set thread priority to max");
|
eprintln!("failed to set thread priority to max");
|
||||||
}
|
}
|
||||||
|
|
||||||
let one_thousand = &BigUint::from(1_000u16);
|
const SPLITTER: u128 = 10000u128;
|
||||||
let one_hundred = &BigUint::from(100u8);
|
let one_thousand = &BigUint::from(SPLITTER*10);
|
||||||
|
let one_hundred = &BigUint::from(SPLITTER);
|
||||||
let ten = &BigUint::from(10u8);
|
let ten = &BigUint::from(10u8);
|
||||||
|
|
||||||
|
|
||||||
@ -74,14 +79,18 @@ fn main() {
|
|||||||
let max = BigUint::from(i+1)*work_uint;
|
let max = BigUint::from(i+1)*work_uint;
|
||||||
let mut primecache = vec![];
|
let mut primecache = vec![];
|
||||||
loop {
|
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());
|
primecache.push(number.clone());
|
||||||
//println!("Found a prime {} {}",number, primecache.len());
|
//println!("Found a prime {} {}",number, primecache.len());
|
||||||
}
|
}
|
||||||
if (&number * one_thousand)/&max/ten == &number/&max*one_hundred {
|
if (&number * one_thousand)/&max/ten == &number/&max*one_hundred {
|
||||||
|
let tried_getting = SystemTime::now();
|
||||||
let mut new_primecache = arcclone.lock().unwrap();
|
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.append(&mut primecache);
|
||||||
new_primecache.sort();
|
new_primecache.sort();
|
||||||
new_primecache.dedup();
|
new_primecache.dedup();
|
||||||
@ -96,51 +105,43 @@ fn main() {
|
|||||||
|
|
||||||
let mut new_primecache = arcclone.lock().unwrap();
|
let mut new_primecache = arcclone.lock().unwrap();
|
||||||
new_primecache.append(&mut primecache);
|
new_primecache.append(&mut primecache);
|
||||||
drop(primecache);
|
|
||||||
new_primecache.sort();
|
new_primecache.sort();
|
||||||
new_primecache.dedup();
|
new_primecache.dedup();
|
||||||
|
|
||||||
true
|
|
||||||
});
|
});
|
||||||
joins.push(tprimes);
|
joins.push(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
for handle in joins {
|
||||||
let mut njoins = vec![];
|
handle.join().unwrap();
|
||||||
for join in joins {
|
|
||||||
if join.is_finished() {
|
|
||||||
join.join().unwrap();
|
|
||||||
} else {
|
|
||||||
njoins.push(join);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
joins = njoins;
|
|
||||||
if joins.len()==0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut primes = primearc.lock().unwrap().to_vec();
|
let mut primes = primearc.lock().unwrap().to_vec();
|
||||||
|
|
||||||
let removed = (primes.len()-n as usize).clamp(0, primes.len());
|
let removed:i32 = if primes.len() > NU {
|
||||||
if removed != 0 {
|
let mut rem = 0;
|
||||||
println!("removing {removed} primes");
|
loop {
|
||||||
for _ in 0..removed {
|
if primes.len() <= NU {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rem+=1;
|
||||||
primes.pop();
|
primes.pop();
|
||||||
}
|
}
|
||||||
}
|
rem
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
let added = n as usize-primes.len();
|
let added = NU-primes.len();
|
||||||
if primes.len() < n as usize {
|
if primes.len() < NU {
|
||||||
println!("Less primes than expected!");
|
println!("Less primes than expected!");
|
||||||
let mut number = BigUint::from(THREADS)*BigUint::from(workloads);
|
let mut number = BigUint::from(THREADS)*BigUint::from(workloads);
|
||||||
let inc = BigUint::from(1u8);
|
let inc = BigUint::from(1u8);
|
||||||
loop {
|
loop {
|
||||||
number = number + &inc;
|
number += &inc;
|
||||||
if prime_utils::is_prime(&number, &primes) {
|
if prime_utils::is_prime(&number, &primes) {
|
||||||
primes.push(number.clone());
|
primes.push(number.clone());
|
||||||
}
|
}
|
||||||
if primes.len() == n as usize {
|
if primes.len() == NU {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,12 +151,25 @@ fn main() {
|
|||||||
let difference = new_sys_time.duration_since(sys_time)
|
let difference = new_sys_time.duration_since(sys_time)
|
||||||
.expect("Clock may have gone backwards");
|
.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!("primes added: {} | % added: {}% | removed: {}",added,(added as f64)/primes.len() as f64*100.0,removed);
|
||||||
println!("last prime approx: {}",nthprime_approx);
|
|
||||||
|
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:?}");
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user