Go死码消除

概念:

死码消除(dead code elimination, DCE) 是一种编译器优化技术, 作用是在编译阶段去掉对程序运行结果没有任何影响的代码

逃逸分析,内联优化并称为 Go编译器执行的三个重要优化


效果:

对于 const.go代码如下:

go 复制代码
package main

import "fmt"

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

const a, b = 10, 20

func main() {
	if max(a, b) == a {
		fmt.Println(a)
	}
}

对于var.go代码如下:

go 复制代码
package main

import "fmt"

func max2(x, y int) int {
	if x > y {
		return x
	}
	return y
}

var x, y = 10, 20

func main() {
	if max2(x, y) == x {
		fmt.Println(x)
	}
}

两个文件的差异,只在于 两个参数 是变量还是常量

分别编译 const.govar.go, 生成的二进制文件大小如下:

go build -o 想要生成的二进制名称 想要编译的.go文件

不难发现, constvar 体积小了约 10%

为何如此?

首先编译器会对max函数 进行内联优化, const.go 优化后如下:

go 复制代码
package main

import "fmt"

const a, b = 10, 20

func main() {
	var result int
	if a > b {
		result = a
	} else {
		result = b
	}
	if result == a {
		fmt.Println(a)
	}
}

因为 ab 是常量, 永远有a<b, 编译器可以在编译时证明该分支永远不会为true, 因此编译器可以进一步优化代码为:

if a > b {}这个分支被消除了,这称为分支消除

又知道结果总是等于b,因此编译器还将进一步将代码优化为:

go 复制代码
package main

const a, b = 10, 20

func main() {
	const result = b

}

最后就是:

go 复制代码
package main

func main() {
}

而对于var.go, 参数为 全局变量 不为常量,编译器并不知道运行过程中x、y会不会发生改变, 因此不能进行死代码消除.

这部分代码被编译到最终的二进制程序中, 造成 二进制文件 varconst 体积大了约 10%

分支消除是死码消除一种. 使用静态证明来表明一段代码永远不可达,通常会被称为死代码,它不需要在最终的二进制文件中编译和优化.

编译器在编译阶段, 死码消除与内联优化一起工作, 可以减少循环和分支产生的代码数量

相关推荐
张声录137 分钟前
使用client-go在命令空间test里面对pod进行操作
开发语言·后端·golang
新智元1 小时前
AI卷翻科研!DeepMind 36页报告:全球实验室被「AI科学家」指数级接管
人工智能·后端
Adolf_19931 小时前
Django 自定义路由转换器
后端·python·django
ᝰꫝꪉꪯꫀ3612 小时前
JavaWeb——Mybatis
java·开发语言·后端·mybatis
机器之心2 小时前
跨模态大升级!少量数据高效微调,LLM教会CLIP玩转复杂文本
人工智能·后端
爱上语文3 小时前
Http 响应协议
网络·后端·网络协议·http
Smilejudy4 小时前
三行五行的 SQL 只存在于教科书和培训班
后端·github
爱上语文4 小时前
Http 请求协议
网络·后端·网络协议·http
贝克街的天才4 小时前
据说在代码里拼接查询条件不够优雅?Magic-1.0.2 发布
java·后端·开源
monkey_meng4 小时前
【Rust Iterator 之 fold,map,filter,for_each】
开发语言·后端·rust