在 Rust 中设置对象参数的性能

Performance of setting parameters of an object in Rust

到目前为止,我一直想知道在 Rust 中遇到的不同的实例化结构的方法。因此,当一切都是 public:

时,手动设置所有字段的方式最多 basic/simple
let a = Structure { arg1: T, arg2: T, ... }

当需要隐私和更好的界面 and/or 默认值时,通常使用 'contructors' 例如 new() 等:

let a = Structure::new(arg1, arg2, ...)

现在,到目前为止,这对我来说有点意义。然而,似乎还有第三种常见的方式来做同样的事情,这让我最困惑。这是一个具体的例子:

let mut image_file = OpenOptions::new()
                        .write(true)
                        .truncate(true)
                        .create(true)
                        .open(file_path)
                        .unwrap();

所以我的问题是:

  1. 这些不同的解决方案(如果有的话)对性能有何影响?
  2. 每个的一般优点和缺点是什么?
  3. 是否有更多方法可以做到这一点?
  4. 最佳做法是什么?

您已经确定了 3 种创建 struct 的方法:

  1. 直接:直接初始化其字段,
  2. 构造函数:调用初始化 struct
  3. 的单个函数
  4. Builder:组装 struct 个元素,然后最终初始化一个 struct

Are there more ways of doing the same?

直接初始化有两种变体:直接初始化每个字段,或者初始化几个字段并 "defaulting" 其他字段 struct S { f0, .. OTHERS } 其中 OTHERS 是 [=16= 的实例].

Constructor 和 Builder 方法有指数级的变化,具体取决于您如何对参数进行分组,在某些情况下,两者之间的界限会很模糊。

但是,所有方法都必须在某个点收敛并使用 (1) 创建 S.

的实例

What are general benefits and disadvantages of each?

这在某种程度上...无关紧要。

3 个备选方案中的每一个都满足不同的需求:

  • 直接初始化需要可访问字段;由于 pub 字段很少见,因此它主要在板条箱中使用,但客户无法使用。
  • Constructor 和 Builder 允许建立不变量,因此是主要客户端的接口。

构造函数简单但不灵活:在不破坏向后兼容性的情况下不能添加新参数(当然,另一个构造函数可以);另一方面,Builder 是灵活的,但代价是冗长。

What are the performance impact of these different solutions ( if any )?

理想情况下,在优化的二进制文件中,Constructor 和 Builder 应该具有相同的成本。如果重要,请配置文件。

直接初始化将比建立不变量的任何一个更快,因为它没有。不过,比较非等效功能的性能并不重要。

Which is the best practice?

避免直接初始化。

直接初始化不建立不变量,建立不变量取决于周围的代码,因此这意味着任何时候使用直接初始化都会重复不变量检查代码,这违反了 DRY 原则。

直接初始化也有悖于封装,阻止了底层结构的任何进一步更改,直至所使用字段的类型。这通常是不可取的。

一如既往地有例外。最突出的是实现 Constructor 或 Builder 需要使用直接初始化。

在 Constructor 和 Builder 之间进行选择更加主观。一般来说,当参数很少时,我推荐使用构造函数,即使这意味着要写几个参数,例如Vec::{new, with_capacity}。如果需要为有意义的每个参数组合编写一个构造函数,那么当构造函数的数量失控时,请改用生成器。