【发布时间】:2016-05-28 03:13:45
【问题描述】:
这是我的 Python 代码:
len_sums = 0
for i in xrange(100000):
set_1 = set(xrange(1000))
set_2 = set(xrange(500, 1500))
intersection_len = len(set_1.intersection(set_2))
len_sums += intersection_len
print len_sums
这是我的 Rust 代码:
use std::collections::HashSet;
fn main() {
let mut len_sums = 0;
for _ in 0..100000 {
let set_1: HashSet<i32> = (0..1000).collect();
let set_2: HashSet<i32> = (500..1500).collect();
let intersection_len = set_1.intersection(&set_2).count();
len_sums += intersection_len;
}
println!("{}", len_sums);
}
我相信这些大致相同。我得到以下性能结果:
time python set_performance.py
50000000
real 0m11.757s
user 0m11.736s
sys 0m0.012s
和
rustc set_performance.rs -O
time ./set_performance 50000000
real 0m17.580s
user 0m17.533s
sys 0m0.032s
使用cargo 和--release 构建会得到相同的结果。
我意识到 Python 的 set 是用 C 实现的,因此预计会很快,但我没想到它会比 Rust 更快。是不是必须做 Rust 不需要的额外类型检查?
也许我在编译 Rust 程序的过程中遗漏了一些东西,是否还有其他我应该使用的优化标志?
另一种可能是代码并不完全等价,Rust 做了不必要的额外工作,我是否遗漏了什么?
Python 版本:
In [3]: import sys
In [4]: sys.version
Out[4]: '2.7.6 (default, Jun 22 2015, 17:58:13) \n[GCC 4.8.2]'
Rust 版本
$ rustc --version
rustc 1.5.0 (3d7cd77e4 2015-12-04)
我使用的是 Ubuntu 14.04,我的系统架构是 x86_64。
【问题讨论】:
-
当我将集合构建移出循环并仅重复交集时,当然对于这两种情况,Rust 都比 python2.7 快。所以这个问题有点错误。
-
@bluss 好点,在我的机器上
rust只快一点点,0m4.168s与0m3.838s。并且初始化花费了很多时间。再次感谢。 -
@bluss 但是如果我在 PyPy3 上使用
set1 & set2,我会得到 1.0s vs 2.3s,所以 Python 重新领先;P