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

问题描述 投票:0回答:1

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

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 一样快?是什么造成了这样的差异?

performance rust pycharm
1个回答
1
投票

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

  • cargo run
    Elapsed time: 267.3377065s
  • cargo run --release
    Elapsed time: 212.5371301s

现在让我们在没有

println
的情况下再次运行它,因为我怀疑这些是代码缓慢的主要原因。事实上,您的代码在 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
© www.soinside.com 2019 - 2024. All rights reserved.