I'm experiencing weird performance characteristics with this code depending on how I run it:
use std::time::Instant;
fn main() {
let start_time = Instant::now();
for p in 1..10000000 {
if prime_check(p as f64) {
println!("{} is prime", p);
}
}
let end_time = Instant::now();
let elapsed_time = end_time - start_time;
println!("Elapsed time: {:?}", elapsed_time);
}
fn prime_check(p: f64) -> bool {
let k: u64 = p.sqrt() as u64;
for j in 2..=k {
if p % j as f64 == 0.0 {
return false;
}
}
true
}
When I hit Alt+Shift+F10 in PyCharm with the Rust plugin, I get this:
9999943 is prime
9999971 is prime
9999973 is prime
9999991 is prime
Elapsed time: 11.537594s
When I build and run executable with rustc, I get this:
PS C:\Users\User\Desktop\Proj\Rs\src> rustc -O main.rs
9999943 is prime
9999971 is prime
9999973 is prime
9999991 is prime
Elapsed time: 37.1560723s
I tried adding this to Cargo.toml
but it made no difference:
[profile.dev]
opt-level = 3
How can I make rustc produced executable as fast as PyCharm? What causes such a difference?
For me, your code ran in:
cargo run
: Elapsed time: 267.3377065s
cargo run --release
: Elapsed time: 212.5371301s
Now let's run it again without the println
s, because I suspect those are the main reason why your code is slow. And the fact that your code performs different in PowerShell and PyCharm is because their println
handling is different.
use std::time::Instant;
fn main() {
let start_time = Instant::now();
let mut count: u64 = 0;
for p in 1..10000000 {
if prime_check(p as f64) {
count += 1;
}
}
let end_time = Instant::now();
let elapsed_time = end_time - start_time;
println!("Found {} primes.", count);
println!("Elapsed time: {:?}", elapsed_time);
}
fn prime_check(p: f64) -> bool {
let k: u64 = p.sqrt() as u64;
for j in 2..=k {
if p % j as f64 == 0.0 {
return false;
}
}
true
}
cargo run
:
Found 664580 primes.
Elapsed time: 54.3782759s
cargo run --release
:
Found 664580 primes.
Elapsed time: 30.7077071s
I suspect the output of this code will now perform similarly in PowerShell and PyCharm.
As a further remark, I'd like to mention that your implementation of prime_check
is dangerous - using f64
will introduce rounding errors at a certain point, and it will produce incorrect results.
Use u64
instead:
use std::time::Instant;
fn main() {
let start_time = Instant::now();
let mut count: u64 = 0;
for p in 1..10000000 {
if prime_check(p) {
count += 1;
}
}
let end_time = Instant::now();
let elapsed_time = end_time - start_time;
println!("Found {} primes.", count);
println!("Elapsed time: {:?}", elapsed_time);
}
fn prime_check(p: u64) -> bool {
let k: u64 = (p as f64).sqrt() as u64;
for j in 2..=k {
if p % j == 0 {
return false;
}
}
true
}
Found 664580 primes.
Elapsed time: 9.4109272s