斯蒂芬大帝
简短的回答,是的,编译器优化了这些。但它对intvs uint(大概是任何有符号和无符号整数类型,例如byte)的表现略有不同。在这两种情况下都避免了乘法和除法指令,但它只是无符号整数的单个指令(以及有符号整数的少量指令)。那是因为您的语句对仅对无符号整数完全等效,而对有符号整数不完全等效。更长的答案:采取一个简单的程序,如:package mainfunc 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即完全相同的指令。对于您给出的每个示例都是如此。