首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >rust vs c性能

rust vs c性能
EN

Stack Overflow用户
提问于 2014-10-09 22:04:58
回答 2查看 15.2K关注 0票数 23

我想学习一点关于rust任务的知识,所以我做了一个PI的蒙特卡洛计算。现在我的困惑是,为什么单线程C版本比4向线程Rust版本快4倍。很明显,我做错了什么,或者我的心理表现模型偏离了。

下面是C语言版本:

代码语言:javascript
复制
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

#define PI 3.1415926535897932

double monte_carlo_pi(int nparts)
{
    int i, in=0;
    double x, y;
    srand(getpid());

    for (i=0; i<nparts; i++) {
        x = (double)rand()/(double)RAND_MAX;
        y = (double)rand()/(double)RAND_MAX;

            if (x*x + y*y < 1.0) {
            in++;
        }
    }

    return in/(double)nparts * 4.0;
}

int main(int argc, char **argv)
{
    int nparts;
    double mc_pi;

    nparts = atoi(argv[1]);
    mc_pi = monte_carlo_pi(nparts);
    printf("computed: %f error: %f\n", mc_pi, mc_pi - PI);
}

Rust版本不是逐行端口:

代码语言:javascript
复制
use std::rand;
use std::rand::distributions::{IndependentSample,Range};

fn monte_carlo_pi(nparts: uint ) -> uint {
    let between = Range::new(0f64,1f64);
    let mut rng = rand::task_rng();
    let mut in_circle = 0u;
    for _ in range(0u, nparts) {
        let a = between.ind_sample(&mut rng);
    let b = between.ind_sample(&mut rng);

    if a*a + b*b <= 1.0 {
        in_circle += 1;
    }
    }
    in_circle
}

fn main() {
    let (tx, rx) = channel();

    let ntasks = 4u;
    let nparts = 100000000u; /* I haven't learned how to parse cmnd line args yet!*/
    for _ in range(0u, ntasks) {
        let child_tx = tx.clone();
        spawn(proc() {
        child_tx.send(monte_carlo_pi(nparts/ntasks));
        });
    }

    let result = rx.recv() + rx.recv() + rx.recv() + rx.recv();

    println!("pi is {}", (result as f64)/(nparts as f64)*4.0);
}

构建C版本并计时:

代码语言:javascript
复制
$ clang -O2 mc-pi.c -o mc-pi-c; time ./mc-pi-c 100000000
computed: 3.141700 error: 0.000108
./mc-pi-c 100000000  1.68s user 0.00s system 99% cpu 1.683 total

构建Rust版本并对其计时:

代码语言:javascript
复制
$ rustc -v      
rustc 0.12.0-nightly (740905042 2014-09-29 23:52:21 +0000)
$ rustc --opt-level 2 --debuginfo 0 mc-pi.rs -o mc-pi-rust; time ./mc-pi-rust  
pi is 3.141327
./mc-pi-rust  2.40s user 24.56s system 352% cpu 7.654 tota
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-18 09:42:44

正如Dogbert所观察到的,瓶颈是随机数生成器。这里有一个速度很快,并且在每个线程上以不同方式播种的方法

代码语言:javascript
复制
fn monte_carlo_pi(id: u32, nparts: uint ) -> uint {
    ...
    let mut rng: XorShiftRng = SeedableRng::from_seed([id,id,id,id]);
    ...
}
票数 20
EN

Stack Overflow用户

发布于 2020-03-25 12:46:11

有意义的基准测试是一件棘手的事情,因为你有各种各样的优化选项,等等。此外,代码的结构可能会产生巨大的影响。

比较C和Rust有点像比较苹果和橙子。我们通常使用像上面这样的计算密集型算法,但现实世界可能会抛出一条曲线。

话虽如此,一般来说,Rust可以而且确实接近C和C++的性能,而且大多数likey在并发任务上通常可以做得更好。

看看这里的基准测试:

https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust-clang.html

我选择了Rust与C Clang基准测试比较,因为两者都依赖于底层的LLVM。

另一方面,与C gcc的比较得出了不同的结果:

猜猜发生了什么?铁锈仍然领先!

我恳求您更详细地探索Benchmark Game站点。在某些情况下,C语言在某些情况下会超越Rust。

通常,当您创建现实世界的解决方案时,您希望针对特定的情况进行性能基准测试。一定要这样做,因为你经常会对结果感到惊讶。永远不要假设。

我认为太多时候,基准被用来转发“我的语言比你的语言更好”风格的rwar。但作为一个在他漫长的职业生涯中使用过20多种计算机语言的人,我总是说,这是一个关于工作的最佳工具的问题。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26280533

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档