我有类似下面的代码
let x = Arc::new(Mutex::new(Thing::new()));
work_on_data(x.clone());
do_more_work_on_data(x.clone());
x
在第二个功能之后不使用,因此不需要第二个克隆。我应该clone()
手动删除还是对其进行优化?
为什么不?
优化编译器的首要原则是as-if规则,该规则指定只要编译器可以证明优化是不可观察的,就可以优化任何东西。
注意:这是某些语言的基础,允许进行特定的优化。
因此,例如:
#[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
}
编译器完全浏览了我们的代码(实际上,我不得不使用extern函数来强制其在中发出一些代码main
)。
那么,您的情况如何?
老实说,这要困难得多。
具体来说,由于以下原因,语义可能会发生变化Drop
:
do_more_work_on_data(x.clone())
,x
可以确保在执行结束后将其丢弃,因此在当前函数结束时Drop
执行的任何副作用,do_more_work_on_data(x)
,x
可能会在do_more_work_on_data
OR的末尾删除,也可能会在其中的更早位置删除。因此,为了证明优化是不可观察的,编译器必须证明:
Drop
没有效果,Drop
将在的最后执行do_more_work_on_data
,该操作与紧随其后的执行相同,这有多大可能?
该Drop
实施Mutex
需要调用FFI,所以从优化的角度来看它具有可观察到的效果。
因此,这全都取决于是否do_more_work_on_data
内联。如果确实如此,那么确实可以将多余的部分clone
进行优化。如果没有,我不会屏住呼吸。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句