经过一些重构后,我对代码中一些看似无害的更改造成的性能损失感到困惑。事实证明,这似乎是由这段代码引起的:
let mut frame = Self {
locals: vec![Value::Nil; block.blk_info.nb_locals],
...
};
...这显然比此代码慢:
let mut frame = Self {
locals: (0..block.blk_info.nb_locals).map(|_| Value::Nil).collect(),
...
};
这正常吗?
vec!
宏应该不是使用 n
默认值初始化向量的最优化方法吗?
我对两个版本的代码都进行了基准测试,第二个版本实际上更快。如果没有人能够重现这一点,则可能是由我的基准运行程序的错误报告引起的,但我对此表示怀疑。不过,我没有尝试查看生成的程序集,因为这会非常耗时,但如果我没有得到答案并且我太好奇了,我可能会这样做。
当
Value
具有非直接的 Clone
实现(例如,具有包含 String
的变体的枚举)时,可能会发生这种情况。
当类型不是
Copy
时,vec![]
宏会克隆每个元素提供的值(并在最后重用它,以保存克隆)。
如果 LLVM 无法优化
Clone
实现以返回提供的相同值(没有分支或任何东西),那么每次创建一个新值会更便宜,这就是第二个片段的作用。
第二个片段也将(像第一个片段一样)避免增长检查,因为范围是
TrustedLen
。