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

时间:2019-12-18 12:57:54

标签: go compiler-optimization

给出一个迭代:

 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,然后再开始循环?

2 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:2)

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