我很好奇使用微优化是否合理
a / 2与a >> 1当a为整数a * 2 VS a << 1a % 2 VS a & 1我知道任何体面的C编译器都能很好地处理这个问题.另外请不要写关于过早优化,因为这些技术是如此明显,甚至不是优化,更像是喜欢如何编写代码.
PS我尝试做基准测试,时间上的差异没有统计学意义.我不知道如何检查go的字节码,所以谢谢你的指点.
Dav*_*e C 10
简而言之,是的,编译器优化了这些.但是对于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
}
Run Code Online (Sandbox Code Playgroud)
并且运行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 ,
Run Code Online (Sandbox Code Playgroud)
这BX是参数,DX并且BX似乎是两个结果(BX被重用作结果之一).这里它们略有不同,但只有几条指令(查看显示的源行号)并且没有任何除法或乘法指令(因此基本上同样快).差异是由于算法与逻辑转换以及Go如何对负值进行修改.
您可以通过更改int为uint程序来确认这一点,然后输出包含以下内容:
0x0008 00008 (…/opt.go:18) ANDQ $1,CX
0x000c 00012 (…/opt.go:19) ANDQ $1,BX
Run Code Online (Sandbox Code Playgroud)
即完全相同的指令.对于您给出的每个示例都是如此.
| 归档时间: |
|
| 查看次数: |
149 次 |
| 最近记录: |