IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]Go和Rust计算性能大比武

    abv123456789发表于 2016-07-31 15:05:57
    love 0

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

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

    当然,光说不干空把式,在学Rust途中,笔者肯定会对Go和Rust进行大量的对比和性能测试,这里先来一个多线程下简单计算的对比。


    一、启动8个线程(mac笔记本是4核8u),每个线程执行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);
    }
    这里注意,我们使用realse发布模式:cargo build --release

    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还有待提高~

    补充:当线程数进一步增加时,例如10,rust和Go的对比来到了14ms vs 19ms;如果是15个线程,那就是15ms vs 24ms;20个线程,19ms vs 37ms;30个线程,26ms vs 50ms。因此可以看出,如果是实时计算系统,那rust的吞吐量对于Go还是有一定优势的,基于线程和goroutine的调度模式还是有差别的。

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

    广告时间

    欢迎大家加入Golang隐修会,QQ群894864,欢迎加入这个大家庭,这里有所有你想要的,而且热心大神很多哦!




沪ICP备19023445号-2号
友情链接