如果 Rust 会立即删除 clone(),我们能确定它会优化它吗?

Can we be sure that Rust will optimize out clone() if it is going to dropped immediately?

提问人:Dunedubby 提问时间:11/2/2023 最后编辑:Dunedubby 更新时间:11/2/2023 访问量:78

问:

显然,在 99% 的情况下,它是否存在并不重要,而只是为了帮助像我这样愚蠢焦虑的开发人员在晚上睡个好觉:

假设您有调用复杂库函数的代码,该函数返回一个可变引用,然后您想要返回该引用。碰巧此引用是实现 Clone 的类型。因此,为了避免重构过多,您可以执行以下操作:

fn common_behavior(specs: Specs) -> ClonableThing {

    let mut intermediate_thing = IntermediateThing::new(specs);

    let clonable_thing: &mut ClonableThing = intermediate_thing.create_mut_ref_to_thing();

    // Will the clone here be reliably optimized out?
    std::mem::replace(clonable_thing, clonable_thing.clone())
}

显然,当其他一切都超出范围时,生成的替换值会立即被丢弃,但我们可以期望克隆操作本身不会发生吗?这是假设这是一个相当复杂的结构,但克隆本身只是由 .clonable_thing.clone()intermediate_thingintermediate_thing#[derive(Clone)]

Rust 编译器优化

评论

0赞 Chayim Friedman 11/2/2023
为什么这个怪物而不是等效的,而且要短得多?clonable_thing.clone()
1赞 Chayim Friedman 11/2/2023
#[derive(Clone)]可以执行任意代码,因为它只是对字段的 .Clone
1赞 Chayim Friedman 11/2/2023
请注意,如果实现,可能会更快。或者,如果它有一些便宜的默认设置,那么.ClonableThingDefaultstd::mem::take(clonable_thing)std::mem::replace(clonable_thing, cheap_to_make_default)
0赞 Dunedubby 11/2/2023
这些都是一些非常好的观点。(或者,谢谢你的提示!)的想法是希望在不明确复制的情况下获得原件。当然,大多数时候这并不重要。replacetakeClonableThing
0赞 Chayim Friedman 11/2/2023
只有更改某些数据才重要,这将非常奇怪。Clone

答:

4赞 Yoric 11/2/2023 #1

编译器不保证这一点。特别是,你的调用可能会产生副作用,在这种情况下,编译器不允许对其进行优化。clone()

在实践中,如果你的实现很简单(几乎总是如此),它通常会被优化掉,但唯一能 100% 确定的方法是反汇编代码。clone()

评论

3赞 Colonel Thirty Two 11/2/2023
值得注意的是:克隆在这方面并不特别。克隆比任何其他功能都更优化,没有特别的保证。
2赞 Chayim Friedman 11/2/2023
@ColonelThirtyTwo 实际上,有点特别,因为标准库中有各种容器可以用按位复制(通过专用化)替换对 的调用,其中 .Cloneclone()T: Copy
0赞 Dunedubby 11/2/2023
今天学到了一些新东西!是否有任何关于那些容器的文档?clone()
2赞 Chayim Friedman 11/2/2023
@Dunedubby 并非如此,只是克隆文档说 if ,必须等同于按位副本。但是您可以查看实现,例如。doc.rust-lang.org/stable/src/core/array/mod.rs.html#400T: Copyclone()