memory - 克隆语句是否被优化过?

标签 memory rust clone

我有类似下面的代码

let x = Arc::new(Mutex::new(Thing::new()));

work_on_data(x.clone());
do_more_work_on_data(x.clone());

x 没有在第二个函数之后使用,因此不需要第二个克隆。我应该手动删除 clone() 还是对其进行优化?

最佳答案

为什么不呢?

优化编译器的首要原则是假设规则,它指定只要编译器可以证明优化是不可观察的,就可以优化任何东西。

注意:这是在某些允许特定优化的语言之上的。

例如:

#[derive(Clone, Debug)]
struct MyDummyType(u64);

extern {
    fn print_c(_: *const ());
}

#[inline(never)]
fn print(dummy: MyDummyType) {
    unsafe { print_c(&dummy as *const _ as *const _) }
}

fn main() {
    let x = MyDummyType(42);
    print(x.clone());
    print(x.clone());
}

产生以下 main:

; Function Attrs: nounwind uwtable
define internal void @_ZN8rust_out4main17h0c6f2596c7f28a79E() unnamed_addr #1 {
entry-block:
  tail call fastcc void @_ZN8rust_out5print17h1f2d1a86beea10d7E(i64 42)
  tail call fastcc void @_ZN8rust_out5print17h1f2d1a86beea10d7E(i64 42)
  ret void
}

编译器完全看穿了我们的代码(实际上我不得不使用一个外部函数来强制它在 main 中发出一些代码)。


那么,你的情况呢?

老实说,这要困难得多。

具体来说,由于 Drop,语义可能会发生变化:

  • 使用 do_more_work_on_data(x.clone())x 保证在执行结束后 被删除,因此任何一方 - Drop 的效果在当前函数的末尾执行,
  • 对于 do_more_work_on_data(x)x 可能do_more_work_on_data 的末尾被丢弃,或者它可能是较早地掉落在某处。

所以为了证明优化不可观察,编译器必须证明:

  • 要么 Drop 没有效果,
  • 或者 Drop 将在 do_more_work_on_data 的最后执行,这与紧随其后的相同,
  • 或者……?

这有多大可能?

MutexDrop 实现需要调用 FFI,因此从优化器的角度来看,它具有可观察到的效果。

所以这一切都取决于 do_more_work_on_data 是否被内联。如果是这样,确实可以优化多余的 clone。如果没有,我不会屏住呼吸。

关于memory - 克隆语句是否被优化过?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42669949/

相关文章:

rust - 返回并使用匹配的通用类型

rust - 不能借用 `self.hash` 作为可变的,因为它也被借用为不可变的

python - Heroku Web dyno 运行 Django 应用程序不释放内存

python - 将列表的 LARGE 字符串表示形式转换为列表 Python 3

linux - 如何跟踪Linux中进程的CPU/内存使用情况?

rust - 如何配置 actix-web 以接受来自任何来源的 CORS 请求?

c++ - 如果我不将预写的字符串保存到变量中,它是否还在内存中?

android - 如何以编程方式创建 ImageView 对象的多个副本?

angularjs - 在 AngularJs 中克隆元素(绑定(bind)和所有)

javascript - jQuery 触发器在克隆后不触发