这两个星期一直在研究rust,之前自己做的这个算法一个典型的生产者和消费者的题目和实现是用java写的,所以希望能用rust也实现了一遍,实际情况下比较一下两者有什么不一样。
下面是一些感受
1. rust快
同样的leader和follower都是500的话,理论上是要开1000个线程的。在我的外星人电脑上面,java要用到26秒,而rust2秒就跑完了。想象一下,本来要买10台服务器的,现在买一台就可以了。当然了,得准备一份优厚的待遇来招呼这个还不存在的rust攻城狮。
========
2015年6月4日注:这个是我之前写错了。在java的程序里加了sleep,把sleep去掉后,java需要5秒钟,不是26秒。不过毕竟rust刚出来,应该还有不少优化的空间。
2015年6月13日注:把java和rust的所有打印调试信息去掉之后,并编译为release版本,两者的运行时间都非常短。只有去到leader和follower都等于2000的时候,才看得到有运行时间,惊讶的是java和rust一样快,我之前的测试方法不够准确。
2015年9月2日注:今天仔细地做了测试对比,环境是外星人mx17(i7-4700MQ 2.4g + 8g 内存),每个数据都是采样10次取平均,下面是运行时间的对比
leader和follower的数量 实现方式 |
500条 | 1000条 | 2000条 |
Java(LinkedList+锁) | 878ms | 1278ms | 2547ms |
Java(LinkedBlockingQueue) | 1129ms | 1698ms | 2839ms |
rust | 931ms | 2401ms | 6708ms |
1. rust由于ownership机制,在实现中会比java不得不发送一次响应请求invitationresult到channel,所以性能上反而比java落后2倍以上。
2. rust的消息体invitation实现copy和clone与否,运行效率都差不多。
3. rust使用sync_channel代替channel后,性能下降较大。
java毕竟流行了十几年,jvm已经得到了很大的优化。rust作为新生的语言,应该还有很大的优化空间。
2. rust没有java的object.wait()方法
java的object有内置的wait和notify来进行线程间的通知和阻塞等待。而rust也有类似的,叫Convdar,但试用了一下,感觉不好用,换成用channel来做线程间发送数据,一样可以。
3. rust创建一个结构时,所有成员都要初始化,rust没有空指针
rust是没有类class的概念,只有结构struct,函数或方法function和接口trait。在例子里面,receiver在创建Follower和Leader的时候是未知的,但rust一定要我给个值,我如果换成是Option<Receiver>吧,待会unwrap()的时候又会报move相关的编译错误,搞的我只能先弄个假的上去,后来再覆盖掉。那如果弄成指针或者引用又如何?对不起,由于rust对于对象生命周期的管理,用了指针就要加上lifetime,这个东西一加上,其他都要跟着加,难看不说,还会带来更多莫名其妙的编译错误。能不用lifetime尽量别用这玩意。
4. rust的match模式匹配挺好用,经常用于错误值检查,比java的try catch来得优雅和高效,错误值返回也是我一直想要的功能
例如:
str => match str.parse::<i32>(){
Err(e) => { println!("{}",e);return;}
Ok(i)=> i
}
}
5. rust里,如果一个变量需要多线程同时访问,通常就定义成Arc<Mutex<T>>
如下面加粗的两行
let mut fo