在 Exercism 网站上解决此练习时,我使用了标准数学。Pow包函数获得两个的提升幂。return uint64(math.Pow(2, float64(n-1)))在检查了社区解决方案之后,我发现了一个使用位移来实现相同目标的解决方案:return uint64(1 << uint(n-1)), nil令我惊讶的是,两者之间有很大的性能差异:位移数学pow我以为Go编译器会识别出这种数学。Pow使用常量2作为基础,并且只是自己使用位移位,而我没有明确地这样做。我能看到的唯一其他区别是 float64 的转换和数学运算。Pow 在浮点数上运行,而不是在整数上运行。为什么编译器不优化电源操作以实现类似于位移位的性能?
3 回答
MYYA
TA贡献1868条经验 获得超4个赞
首先,请注意,这是问题中出现的表达式的更好版本。表达式是一个,所以有效的移位值在 0 到 30 或 62 之间,这取决于 int 的大小。 允许在 0 和 63 之间。uint64(1) << (n-1)uint64(1 << uint(n-1))1<<nintuint64(1) << nn
通常,您建议的优化不正确。编译器必须能够推断出该值是否在特定范围内。n
请参阅此示例(在操场上)
package main
import (
"fmt"
"math"
)
func main() {
n := 65
fmt.Println(uint64(math.Pow(2, float64(n-1))))
fmt.Println(uint64(1) << uint(n-1))
}
输出表明这两种方法是不同的:
9223372036854775808
0
桃花长相依
TA贡献1860条经验 获得超8个赞
- 3 回答
- 0 关注
- 80 浏览
添加回答
举报
0/150
提交
取消