为什么从PyCharm运行时我的可执行文件更快?

vktxenjb  于 8个月前  发布在  PyCharm
关注(0)|答案(1)|浏览(105)

我在运行这段代码时遇到了奇怪的性能特征,这取决于我如何运行它:

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
}

当我用Rust插件在PyCharm中按Alt+Shift+F10时,我得到了这个:

9999943 is prime
9999971 is prime
9999973 is prime
9999991 is prime
Elapsed time: 11.537594s

当我用rustc构建并运行可执行文件时,我得到了这个:

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

我试着把它添加到Cargo.toml,但没有什么区别:

[profile.dev]
opt-level = 3

如何让rustc生成的可执行文件像PyCharm一样快?是什么造成了这种差异?

vwkv1x7d

vwkv1x7d1#

对我来说,你的代码运行在:

  • cargo runElapsed time: 267.3377065s
  • cargo run --releaseElapsed time: 212.5371301s

现在让我们在不使用println s的情况下再次运行它,因为我怀疑这些是您的代码慢的主要原因。事实上,您的代码在PowerShell和PyCharm中执行不同是因为它们的println处理不同。

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

我怀疑这段代码的输出现在在PowerShell和PyCharm中执行类似的操作。
作为进一步的说明,我想提一下prime_check的实现是危险的-使用f64将在某个点引入舍入错误,并且它将产生不正确的结果。
使用u64代替:

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

相关问题