1 回答
TA贡献1827条经验 获得超8个赞
简短的回答,是的,编译器优化了这些。但它对intvs uint(大概是任何有符号和无符号整数类型,例如byte)的表现略有不同。
在这两种情况下都避免了乘法和除法指令,但它只是无符号整数的单个指令(以及有符号整数的少量指令)。那是因为您的语句对仅对无符号整数完全等效,而对有符号整数不完全等效。
更长的答案:
采取一个简单的程序,如:
package main
func main() {}
func div2(a int) {
b := a / 2
c := a >> 1
_, _ = b, c
}
func mul2(a int) {
b := a * 2
c := a << 1
_, _ = b, c
}
func mod2(a int) {
b := a % 2
c := a & 1
_, _ = b, c
}
并运行go build -gcflags="-S"将为您提供汇编输出,例如:
"".mod2 t=1 size=32 value=0 args=0x8 locals=0x0
0x0000 00000 (…/opt.go:17) TEXT "".mod2+0(SB),4,$0-8
…
0x0000 00000 (…/opt.go:17) MOVQ "".a+8(FP),BX
…
0x0005 00005 (…/opt.go:18) MOVQ BX,AX
0x0008 00008 (…/opt.go:18) SARQ $63,AX
0x000c 00012 (…/opt.go:18) MOVQ BX,DX
0x000f 00015 (…/opt.go:18) SUBQ AX,DX
0x0012 00018 (…/opt.go:18) ANDQ $1,DX
0x0016 00022 (…/opt.go:18) ADDQ AX,DX
0x0019 00025 (…/opt.go:19) ANDQ $1,BX
0x001d 00029 (…/opt.go:21) RET ,
这BX是参数 andDX和BX似乎是两个结果(BX作为结果之一重用)。这里它们略有不同,但只有几条指令(查看显示的源代码行号)并且没有任何除法或乘法指令(所以基本上一样快)。差异是由于算法与逻辑转换以及 Go 如何对负值进行 mod 。
您可以通过在程序中更改int为来确认这一点uint,然后输出包含以下内容:
0x0008 00008 (…/opt.go:18) ANDQ $1,CX
0x000c 00012 (…/opt.go:19) ANDQ $1,BX
即完全相同的指令。对于您给出的每个示例都是如此。
- 1 回答
- 0 关注
- 189 浏览
添加回答
举报