为什么创建一个非常大的零大小项向量需要永远,而数组很好?

Luk*_*odt 3 rust

这段代码运行良好:

use std::mem::size_of;

fn main() {
    println!("{}", size_of::<[(); usize::max_value()]>());
    let x = [(); usize::max_value()];
    println!("done");
}
Run Code Online (Sandbox Code Playgroud)

它立即打印0done。数组毕竟是 0 字节大,所以这是意料之中的。

Vec但是,如果我使用 a ,事情看起来会有所不同:

fn main() {
    let x = vec![(); usize::max_value()];
    println!("done");
}
Run Code Online (Sandbox Code Playgroud)

这运行了很长时间并且从不打印done这是为什么?我还希望向量的实际大小为 0。所以它不需要分配或写入任何内存。什么需要这么长时间?

这只发生在我没有优化编译时。通过优化,它立即完成。

Luk*_*odt 9

您的数组表达式[(); usize::max_value()]由编译器直接理解和解释。vec![(); usize::max_value()]另一方面,表达式是一个宏。那么让我们看看它扩展到什么!

使用cargo expand,我得到:

let x = ::alloc::vec::from_elem((), usize::max_value());
Run Code Online (Sandbox Code Playgroud)

您不会在文档中找到这种方法,因为它是doc(hidden). 您可以在此处的源代码中看到它。它委托一个 trait 专门针对某些类型的性能。在这种()情况下,将使用此 impl。这主要是调用私有方法extend_with这里定义

在那里我们终于看到了问题:一个for _ in 1..n循环。如果没有优化,这个循环不会被删除,因此,程序需要永远尝试执行usize::max_value()循环迭代。