编译器是否优化变量声明?
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 位,则 int
和 int64
的大小(以及内存表示和解释)是相同的,这意味着转换不会产生任何成本,它只是改变类型(它是如何解释的)。
编辑: 因为无论如何您都在使用 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,int
与 int64
相同。无需转换。
参考:
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
给定一个迭代:
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 位,则 int
和 int64
的大小(以及内存表示和解释)是相同的,这意味着转换不会产生任何成本,它只是改变类型(它是如何解释的)。
编辑: 因为无论如何您都在使用 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,int
与 int64
相同。无需转换。
参考:
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