考虑到具有很少公共类型和获取方法的示例 struct ,什么时候以及为什么在Ruust中通过值或引用传递简单类型更好?


use chrono::{DateTime, Utc};
pub type Bytes = [u8; 16];
#[derive(Clone, Copy)]
pub struct Uuid(Bytes);


struct X {
    v_str: String,
    v_num: i32,
    v_bool: bool,
    v_uuid: Uuid,
    v_date: DateTime<Utc>,
}
impl X {
    pub fn v_str_ref(&self) -> &str {
        &self.v_str
    }
    pub fn v_str_val(&self) -> String {
        self.v_str.clone()
    }

    pub fn v_num_ref(&self) -> &i32 {
        &self.v_num
    }
    pub fn v_num_val(&self) -> i32 {
        self.v_num
    }

    pub fn v_bool_ref(&self) -> &bool {
        &self.v_bool
    }
    pub fn v_bool_val(&self) -> bool {
        self.v_bool
    }

    pub fn v_uuid_ref(&self) -> &Uuid {
        &self.v_uuid
    }
    pub fn v_uuid_val(&self) -> Uuid {
        self.v_uuid
    }

    pub fn v_date_ref(&self) -> &DateTime<Utc> {
        &self.v_date
    }
    pub fn v_date_val(&self) -> DateTime<Utc> {
        self.v_date
    }
}

以我的理解,数字作为值传递更好,因为引用开销比仅通过值传递的性能更差,而且borrow 判断器规则会使通过引用传递变得不方便.

布尔人似乎遵循数字逻辑.

对于字符串,通过引用传递时性能似乎更好,并且当borrow 判断器处于某种程度时,克隆也很简单.

对于UUID和日期,我会假设应用与字符串相同的规则?

推荐答案

对于简单的整数、浮点数和布尔值,通常通过值传递更好,因为正如您所提到的,它们通常很小.此外,它们通常是Copy个,所以编译器通常会生成大量的副本(希望在优化输出中省略掉这些副本).

标准库的IP地址也为Copy,大约为16个字节.一旦获得的数据大于该值,传递引用通常很有用,因为指针只有4或8个字节(可以放入寄存器中),而较大的值则不能,因此复制它们的开销更大.

由于字符串或VEC中的数据几乎可以任意大小,因此使用适当的引用类型(&str&[T])通常是谨慎的,因为这样可以避免复制所有数据.通常,这些值包含少量的项,但如果您的字符串甚至包含StackOverflow帖子的内容,则制作大量副本可能会非常慢,非常快.同样,对于大多数通用的任意集合也是如此,除非您确定数据总是很小.

Rust相关问答推荐

从Rust调用C++虚拟方法即使在成功执行之后也会引发Access违规错误

有没有更好的方法从HashMap的条目初始化 struct ?

如果成员都实现特征,是否在多态集合上实现部分重叠的特征?

"value is never read警告似乎不正确.我应该忽略它吗?

在Rust中,如果Result是Err,运行副作用(如日志(log)记录)的惯用方法是什么

默认特征实现中的生命周期问题

在生存期内将非静态可变引用转换为范围内的静态可变引用

什么时候使用FuturesOrdered?

为什么 tokio 在以奇怪的方式调用时只运行 n 个任务中的 n-1 个?

用于实现获取 struct 体 id 的特征规范

Boxing 如何将数据从堆栈移动到堆?

将泛型中的 Box 转换为 rust 中的 Box

Google chrome 和 Apple M1 中的计算着色器

为什么Rust中无法推断生命周期?

从Rust 的临时文件中创建引用是什么意思?

RAII 模式的 Rust 解决方案,用于在 new() 和 drop() 上修改另一个对象

当我在 struct 中存储异步函数时,为什么它需要生命周期

用逗号分隔字符串,但在标记中使用逗号

有没有办法隐藏类型定义?

令人困惑的错误消息? (解包运算符)