以下是我的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

Building with cargo--release give the same result.

I realize that Python's set is implemented in C, 和 so is expected to be fast, but I did not expect it to be faster than Rust. Wouldn't it have to do extra type checking that Rust would not?

也许我在编译我的Rust程序时遗漏了一些东西,我应该使用其他优化标志吗?

Another possibility is that the code is not really equivalent, 和 Rust is doing unnecessary extra work, am I missing anything?

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)

I am using Ubuntu 14.04 和 my system architecture is x86_64.

推荐答案

当我将布景建筑移出循环,只重复交叉点时,当然,对于这两种情况,Rust都比Python 2.7快.

我只读过Python3(setobject.c),但Python的实现有一些适合它的东西.

它使用了两个Python set对象使用相同的散列函数这一事实,因此不会重新计算散列.Rust HashSet的散列函数具有实例唯一的键,因此在交集期间,它们必须将一个集合中的键与另一个集合的散列函数重新散列.

另一方面,Python必须 for each 匹配的哈希调用动态键比较函数,如PyObject_RichCompareBool,而Rust代码使用泛型,并将专门化哈希函数和i32的比较代码.在Rust中对i32进行哈希运算的代码看起来相对便宜,而且大部分哈希算法(处理长度超过4字节的输入)都被删除了.


似乎是这套装置的构造使我们的生活和Rust 分开了.事实上,不仅仅是构造,还有一些重要的代码正在运行,以 destruct Rust HashSet.(这是可以改进的,这里的bug:#31711)

Rust相关问答推荐

如何在tauri—leptos应用程序中监听后端值的变化?""

为什么幻影数据不能自动推断?

文档示例需要导入相关的 struct ,但仅在运行测试时.这是故意的行为吗?

为昂贵的for循环制作筛子

为什么Rust不支持带关联常量的特征对象?

try 创建随机数以常量

是否可以使用Serde/Rust全局处理无效的JSON值?

如何将一个矩阵的列分配给另一个矩阵,纳尔代数?

在 Rust 中,在第一个空格上分割字符串一次

如何处理闭包中的生命周期以及作为参数和返回类型的闭包?

仅在使用 &mut 或线程时borrow 的数据在闭包之外转义?

sha256 摘要仅适用于 &*

Rust 文件未编译到 dll 中

通过mem::transmute将数组展平安全吗?

从Rust 的临时文件中创建引用是什么意思?

没有明确地说return会产生错误:match arms have incompatible types

从 HashMap>, _> 中删除的生命周期问题

了解 Rust 闭包:为什么它们持续持有可变引用?

如何在 Rust 中将 bson::Bson 转换为 Vec

有没有办法在 Rust 中对 BigInt 进行正确的位移?