Go死码消除

概念:

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

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


效果:

对于 const.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代码如下:

复制代码
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 优化后如下:

复制代码
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,因此编译器还将进一步将代码优化为:

复制代码
package main

const a, b = 10, 20

func main() {
 const result = b

}

最后就是:

复制代码
package main

func main() {
}

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

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

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

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

参考资料

1

逃逸分析: https://dashen.tech/2021/05/29/golang逃逸技术分析/

2

内联优化: https://dashen.tech/2021/05/22/Go中的内联优化

本文由mdnice多平台发布

相关推荐
咖啡教室12 分钟前
每日一个计算机小知识:Bit和Byte(比特和字节)
后端
咖啡教室22 分钟前
每日一个计算机小知识:Linux
linux·后端
IT_陈寒37 分钟前
Vite 5个隐藏技巧让你的项目构建速度提升50%,第3个太香了!
前端·人工智能·后端
用户40993225021239 分钟前
复杂查询总拖后腿?PostgreSQL多列索引+覆盖索引的神仙技巧你get没?
后端·ai编程·trae
凤山老林1 小时前
排序算法:详解插入排序
java·开发语言·后端·算法·排序算法
低音钢琴2 小时前
【SpringBoot从初学者到专家的成长18】SpringBoot中的数据持久化:JPA与Hibernate的结合
spring boot·后端·hibernate
paopaokaka_luck2 小时前
基于SpringBoot+Vue的社区诊所管理系统(AI问答、webSocket实时聊天、Echarts图形化分析)
vue.js·人工智能·spring boot·后端·websocket
李慕婉学姐2 小时前
Springboot黄河文化科普网站5q37v(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
道之极万物灭2 小时前
Go基础知识(一)
开发语言·后端·golang
Victor3562 小时前
Redis(71)如何确保Redis分布式锁的可靠性?
后端