我在Clippy中运行我的代码,它建议修改以下内容:
const SPECIAL_VALUE: u8 = 0; // May change eventually.
pub fn version1(value: u8) -> bool {
(value >= 1 && value <= 9) || value == SPECIAL_VALUE
}
转到
pub fn version2(value: u8) -> bool {
(1..=9).contains(&value) || value == SPECIAL_VALUE
}
因为它更具可读性。不幸的是,生成的程序集输出的长度是优化级别3的两倍。手动插入它(2嵌套),给出的代码几乎与version1
相同,而且效率也一样。
pub fn manually_inlined(value: u8) -> bool {
(1 <= value && value <= 9) || value == SPECIAL_VALUE
}
如果我删除了|| value == SPECIAL_VALUE
,它们都用相同的解析方法(尽管增加了1条指令以减少参数值,然后再进行比较)。另外,如果我将SPECIAL_VALUE
更改为与范围不相邻的内容,它们都会将其解析为与version2
相同的汇编代码,这就是为什么我将其保留为0
的原因,除非我最终不得不更改它。
我有一个链接,在这里有一个代码:https://rust.godbolt.org/z/bMYzfcYob
为什么编译器不能正确地内联/优化version2
?这是一个“优化错误”吗?或者我误解了Rust的一些语义,也许借用的东西阻止了优化,但是编译器不能因为混叠和引用规则而假定值的变化吗?
在C++中尝试做同样的事情,在这两种情况下都会产生更糟糕的选择(https://godbolt.org/z/zahfz65W3)
编辑:将我的C++版本的编译器更改为GCC,使其在这两种情况下都得到优化。
发布于 2022-03-07 12:38:08
这确实是一个错过的优化机会,现在已经在LLVM中得到了纠正。https://github.com/rust-lang/rust/issues/90609#issuecomment-1046037263。
https://stackoverflow.com/questions/69844819
复制相似问题