美文网首页程序员
Go和Rust简单计算性能PK

Go和Rust简单计算性能PK

作者: Sunface撩技术 | 来源:发表于2017-10-23 15:11 被阅读2288次

    迁移自CSDN:http://blog.csdn.net/erlib/article/details/52078417

    作为Go语言的狂热粉丝最近听说了同样鼎鼎大名的现代化语言-Rust,看了介绍后,发现Rust绝对是一门非常有潜力的系统级语言,因此特抽出业余时间进行了学习。

    在网上有不少关于Go和Rust的对比文章,但是从我个人的观点来看,这两个语言没有什么好对比的,因为它们的使用场景基本没有重叠之处。Go适合网络编程、软实时系统; Rust适合内存使用苛刻、无GC、超高性能的场景,因此这两门语言如果结合起来,完全是一对非常美好的CP,大家觉得呢?

    当然,光说不干空把式,这里先来一个多线程下简单计算的对比。

    环境简介:

    • macbook pro
    • 4核8线程
    • 16G内存

    任务描述:

    • 启动8个线程
    • 每个线程执行500万次计算任务
    • 统计耗时

    Go

    package main  
      
    import (  
        "fmt"  
        "math/rand"  
        //  "runtime"  
        "sync"  
        "time"  
    )  
      
    func main() {  
        st := time.Now()  
        wg := &sync.WaitGroup{}  
        for i := 0; i < 8; i++ {  
            wg.Add(1)  
            go func() {  
                // 防止被编译器优化,随机化初始值  
                x := int(rand.Int31())  
                for i := 0; i < 5000000; i++ {  
                    // 防止被编译器优化,随机化操作  
                    if (x+i)%2 == 0 {  
                        x += i  
                    } else {  
                        x -= i  
                    }  
      
                }  
                fmt.Println(x)  
                wg.Done()  
            }()  
        }  
      
        wg.Wait()  
      
        fmt.Println("time used: ", time.Now().Sub(st))  
    }  
    

    结果:

    1298498081  
    1427131847  
    2019727887  
    939984059  
    336122540  
    1474941318  
    911902081  
    140954425  
    time used:  12.93551ms  
    

    Rust

    extern crate time;  
    extern crate rand;  
      
    use std::thread;  
    use time::*;  
    use rand::Rng;  
    fn main() {  
        let start = time::now();  
      
        let handles: Vec<_> = (0..8)  
            .map(|_| {  
                thread::spawn(|| {  
                    // 防止被编译器优化,随机化初始值  
                    let mut rng = rand::thread_rng();  
                    let mut x = rng.gen::<i32>();  
                    let num = 5_000_000;  
                    for i in 0..num {  
                        // 防止被编译器优化,随机化操作  
                        if (x + i) % 2 == 0 {  
                            x += i;  
                        } else {  
                            x -= i;  
                        }  
                    }  
                    x  
                })  
            })  
            .collect();  
        for h in handles {  
            println!("Thread finished with count={}",  
                     h.join().map_err(|_| "Could not join a thread!").unwrap());  
        }  
      
        let end = time::now();  
        let duration = end - start;  
      
        println!("耗时:{}", duration);  
    } 
    

    结果:

    Thread finished with count=1845603826  
    Thread finished with count=496088980  
    Thread finished with count=-1380406629  
    Thread finished with count=-360370413  
    Thread finished with count=355179270  
    Thread finished with count=119012173  
    Thread finished with count=-229585086  
    Thread finished with count=-736809061  
    耗时:PT0.011544S  
    

    结论

    这里能够看出,在使用8个线程进行简单计算时,Rust的性能是稍高于于Go的,11.5ms vs 12.9ms,并没有太大优势。因此如果不考虑gc、内存控制、泛型等因素,Go必然是第一选择,因为Go的学习曲线比Rust平缓太多了,开发效率也更高,何况Go的异步网络IO也是如此的优秀,这方面Rust还有待提高~

    补充1
    当线程数进一步增加时,例如10,rust和Go的对比来到了14ms vs 19ms;如果是15个线程,那就是15ms vs 24ms;20个线程,19ms vs 37ms;30个线程,26ms vs 50ms。

    因此可以看出,如果是实时计算系统,那rust的吞吐量对于Go还是有一定优势的,基于线程和goroutine的调度模式还是有差别的。

    补充2
    20个线程,每个线程运行50亿次,rust和Go用时,16.5s vs 36秒,内存占用的话都不高,但是看得出来Go的占用一直在上升,rust的内存占用主要在线程上,计算过程中内存并不会增加,十分稳定。至于CPU,毫无疑问都是800%。

    如果您喜欢这篇文章,请点击喜欢;如果想及时获得最新的咨询,请点击关注。您的支持是对作者都是最大的激励,万分感激!By 孙飞

    相关文章

      网友评论

        本文标题:Go和Rust简单计算性能PK

        本文链接:https://www.haomeiwen.com/subject/kurauxtx.html