gpt4 book ai didi

rust - 消费 self 并返回它对性能有何影响?

转载 作者:行者123 更新时间:2023-11-29 08:25:09 28 4
gpt4 key购买 nike

我一直在阅读类似 Why does a function that accepts a Box<MyType> complain of a value being moved when a function that accepts self works? 的问题, Preferable pattern for getting around the "moving out of borrowed self" checker , 和 How to capture self consuming variable in a struct? ,现在我很好奇消费 self 但可能将其返回给调用者的性能特征。

举一个更简单的例子,假设我想创建一个保证非空的集合类型。为此,“删除”操作需要使用集合并有选择地返回自身。

struct NonEmptyCollection { ... }

impl NonEmptyCollection {
fn pop(mut self) -> Option<Self> {
if self.len() == 1 {
None
} else {
// really remove the element here
Some(self)
}
}
}

(我想它也应该返回它从列表中删除的值,但这只是一个例子。)现在假设我调用这个函数:

let mut c = NonEmptyCollection::new(...);
if let Some(new_c) = c.pop() {
c = new_c
} else {
// never use c again
}

对象的内存实际上发生了什么?如果我有这样的代码怎么办:

let mut opt: Option<NonEmptyCollection> = Some(NonEmptyCollection::new(...));
opt = opt.take().pop();

函数的签名并不能保证返回的对象实际上是同一个对象,那么有什么优化可能呢? C++ 返回值优化之类的东西是否适用,允许返回的对象在它之前所在的同一内存中“构造”?如果我可以在上面的接口(interface)和调用者必须处理生命周期的接口(interface)之间进行选择:

enum PopResult {
StillValid,
Dead
};

impl NonEmptyCollection {
fn pop(&mut self) -> PopResult {
// really remove the element
if self.len() == 0 { PopResult::Dead } else { PopResult::StillValid }
}
}

出于性能原因,是否有理由选择这种较脏的接口(interface)?在answer to the second example I linked , trentcl 建议将 Option 存储在数据结构中,以允许调用者就地进行更改,而不是每次执行 remove 后跟 insert时间。这个肮脏的接口(interface)会是一个更快的选择吗?

最佳答案

YMMV

根据优化器的突发奇想,您最终可能会得到:

  • 接近空操作,
  • 一些注册 Action ,
  • 一些位拷贝。

这将取决于是否:

  • 调用是否内联,
  • 调用者重新分配给原始变量或创建一个新变量(以及 LLVM 如何处理重用死空间),
  • size_of::<Self>() .

你得到的唯一保证是不会发生深拷贝,因为没有 .clone()打电话。

对于其他任何事情,您需要检查 LLVM IR 或程序集。

关于rust - 消费 self 并返回它对性能有何影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48226014/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com