Rust 在多大程度上影响了零成本?

To what extent is Rust shadowing zero-cost?

A Zero-Runtime-Cost Mixed List in Rust outlines how to create a heterogenous list in Rust using tuples and normal traits (not trait objects like this question 建议)。该列表似乎严重依赖阴影,并且每次添加新元素时都会有效地更改列表的整个类型。

这个实现对我来说似乎很棒,但是在查看了一些 Rust 的主页和资源之后,我找不到任何地方明确地将阴影定义为零成本。据我所知,反复放弃堆栈上的数据比间接的成本更低,但反复复制和添加到现有数据而不是改变它听起来相当昂贵。

What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand code any better.

  • Bjarne Stroustrup

阴影似乎满足第一个要求,但第二个?

Rust 的阴影实际上是零成本吗?

官方 Rust material 非常努力地从不谈论 "zero cost" 本身,所以你必须在没有进一步限定的情况下引用你看到 "zero cost" 的地方。 The article 声明零 运行时 成本,因此 post 的作者知道这一点。在大多数情况下,"zero cost" 用于 零成本抽象 的上下文中。

您对 Stroustrup 的引用只是部分和间接地涉及零成本抽象。更好的解释,强调我的:

It means paying no penalty for the abstraction, or said otherwise, it means that whether you use the abstraction or instead go for the "manual" implementation you end up having the same costs (same speed, same memory consumption, ...).

这意味着任何时候你看到"zero-cost abstraction",你必须一些东西来比较抽象与;只有这样你才能知道它是否真的是零成本。

我认为阴影甚至不算作 抽象,但让我们假装它确实如此(我会在回答的其余部分表述为我相信它是).

隐藏一个变量意味着有多个同名的不同变量,后面的变量阻止访问前面的变量。非 "abstract" 版本具有多个不同名称的不同变量。我会说拥有两个同名变量 与拥有两个不同名称的变量具有相同的成本 ,因此它是零成本抽象。

另请参阅:


进一步玩游戏,可以问"is having two variables a zero-cost abstraction?"。我会说这取决于变量是什么以及它们之间的关系。

在这个例子中,我会说这是一个零成本的抽象,因为没有比我编写代码更有效的方法了。

fn example() {
    let a = String::new();
    let a = a;
}

另一方面,我想说这不是零成本抽象,因为第一个 a 直到函数结束才会被释放:

fn example() {
    let a = String::new();
    let a = String::new();
}

我可以选择编写它的更好方法是在中间调用 drop。 Rust 不这样做是有充分理由的,但它在内存使用方面 不如 像手写实现那样高效。

另请参阅:

  • Is the resource of a shadowed variable binding freed immediately?