glolang编译器中的空函数优化

Empty function optimization in glolang compiler

golang编译器是否优化空函数?

我希望在构建产品时从 main.go 中删除调试日志代码行

main.go

func main() {
  logging.DebugLog("hey %d", 123)
}

调试模式,

// +build dev
package logging

import (
    "fmt"
)

func DebugLog(pattern string, args... interface{}) {
    msg := fmt.Sprintf(pattern, args...)
    fmt.Printf("debug: %s\n", msg)
}

生产模式,

// +build !dev
package logging

import (
    "fmt"
)

func DebugLog(pattern string, args... interface{}) {}

golang编译器是否会在编译时从main函数中去掉DebugLog函数行?或者只是离开并在 运行 时间内执行?

让我详细回答一下。

答案是肯定的,至少是某个版本的golang编译器。

试验台

go版本go1.13.15linux/amd64

猫./main.go

package main

import (
    "./fc"
)

func main() {
    fc.Dosome()
}

cat ./fc/funcdummy.go

// +build !dev

package fc

func Dosome() {
}

cat ./fc/func.go

// +build dev

package fc

import (
    "fmt"
)

func Dosome() {
    fmt.Println("hello world")
}
go build -tags dev -o ./havetag ./main.go
go build -o ./notag ./main.go
go tool objdump -S ./notag  > ./dumpnotag
go tool objdump -S ./havetag  > ./dumphavetag

结果

grep 'Dosome' -A 5 -B 5 ./dumphavetag

  0x48cf69      483b6110        CMPQ 0x10(CX), SP   
  0x48cf6d      7670            JBE 0x48cfdf        
  0x48cf6f      4883ec58        SUBQ [=14=]x58, SP      
  0x48cf73      48896c2450      MOVQ BP, 0x50(SP)   
  0x48cf78      488d6c2450      LEAQ 0x50(SP), BP   
    fc.Dosome()
  0x48cf7d      0f57c0          XORPS X0, X0        
    fmt.Println("hello world")
  0x48cf80      0f11442440      MOVUPS X0, 0x40(SP) 
  0x48cf85      488d0554120100      LEAQ 0x11254(IP), AX    
  0x48cf8c      4889442440      MOVQ AX, 0x40(SP)

grep 'Dosome' -A 5 -B 5 ./dumpnotag

//empty

因此,我们可以看到,优化了空函数,没有为 golang 编译器添加更多编译标志。

更多

我发现这个 issue 相关,所以你需要现代版本的 go compile。你可以得到你想要的。

We now do whole subtree inlining, and dead code elimination.