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

Does the compiler optimize a variable declaration?

给定一个迭代:

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

Count()returns一个int64,所以我需要一个转换,Count变化,所以我们在这里检查直到Count()returns 一个预期值 - 可能有数千次迭代。

编译器是否优化了这个转换? 还是在开始循环之前先将之前在其他地方使用的 num 转换为 int 而不是 int64 更好?

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

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

编辑: 因为无论如何您都在使用 sleep,所以取消转换将毫无意义。使用使您的代码更具可读性的任何一个。

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 相同。无需转换。

参考:

Intel® 64 and IA-32 Architectures Software Developer Manuals


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