编译器是否优化了变量声明?



给定迭代:

LOOP:
for {       
select {
case <-timeout:
t.Fatal("Timed out")
default:
if Count() == int64(num) {
break LOOP
}
time.Sleep(5 * time.Millisecond)
}
}

Count()返回一个int64,所以我需要一个转换,Count更改,所以我们在这里检查,直到Count()返回一个期望的值 - 可能是数千次迭代。

编译器是否优化了此转换? 还是在开始循环之前先转换num,在其他地方用作int而不是int64

是否优化可能取决于您未显示的其他代码,以及编译器版本/目标体系结构。虽然我怀疑何时涉及并发和其他函数调用,但性能瓶颈将是int=>int64转换。如果您摆脱该转换,您很可能看不到任何区别。

另请注意,如果您使用的体系结构是 64 位,则intint64的大小(以及内存表示和解释(是相同的,这意味着转换不会产生任何成本,它只是更改类型(如何解释(。

编辑:由于您无论如何都在使用睡眠,因此摆脱转换将毫无意义。使用使代码更具可读性的方法。

Go amd64汇编程序:

0000000000457bb0 <main.Equality>:
457bb0:   48 8b 44 24 08          mov    0x8(%rsp),%rax
457bb5:   48 8b 4c 24 10          mov    0x10(%rsp),%rcx
457bba:   48 39 c8                cmp    %rcx,%rax
457bbd:   0f 94 44 24 18          sete   0x18(%rsp)
457bc2:   c3                      retq

正如预期的那样,它很快。

编译器知道,对于amd64,intint64相同。无需转换。

参考:

英特尔® 64 和 IA-32 架构软件开发人员手册


opt.go

package main
//go:noinline
func Equality(a int64, b int) bool {
return a == int64(b)
}
func main() {
var a, b = int64(42), int(39)
println(Equality(a, b))
}

转 储:

$ go build opt.go
$ objdump -d opt > opt.dump

最新更新