共计 3293 个字符,预计需要花费 9 分钟才能阅读完成。
重要阐明:
- 本文仅记录了集体浏览 go release notes 之后的一些浮浅了解,肯定会存在大量的谬误。
- 有很多重要的改变没有被列出(可能是因为自己无奈了解或者不感兴趣)。
- 切记不要当做 Go release notes 的中文翻译,仅仅是一个小笔记。具体的内容请肯定请参考原文阐明。
官网 Release Notes:
https://go.dev/doc/go1.x(替换 url 最初的版本号即可)
因为自己是从 Go 1.3/1.4 阶段开始接触 Go 的,因而 1.5 之前的一些批改就不关注了。
Go 1.5
- GC 改变(打消 stw)。
- 调度器改变(并发度更高)。
- Bootstrapping、移出 C 代码,编译器工具链用 Go(大部分由 C 转化而来);移出 6a/6l/6g 等。
- (负面)编译器的速度极大的变慢。
- 在 x86 下面的动静链接个性。
Go 1.6
- 退出了 race detector。
- 编译器前端解析器手写(不应用 yacc)。
- vendoring;挂掉的时候打出所有 routine 堆栈;GC 优化。
Go 1.7
- 编译器后端优化 SSA(针对 64-bit x86),性能晋升。
- Toolchain 优化:新的导出格局;编译器和链接器性能晋升;更小的二进制输入;
Go 1.8
- Assembler 退出某些 64-bit 机器的新指令。
- 去除 yacc 相干的内容。
- SSA 应用到全副的反对架构上。
- 新的 compiler 前端,用户无感知然而丢后续性能优化十分重要。
- 优化 compiler 和 linker 性能。
- Plugin 的初步反对。
- 优化了 GC 和 defer,以及一些规范库。
Go 1.9
- Package 内并发编译。
- Compiler 和 linker DWARF 信息相干改变。
- ARM assembler
MULA
指令 bug fix。 - 工具 pprof 不须要二进制代码就可能查看各种符号 (代码行等) 信息;
pprof.Do
;pprof.Label 更新。 - GC only blocks the calling routine.
- 新的 bits 规范库;sync.Map 规范库;
Go 1.10
- Build 时候只依照代码来推断是否须要从新编译(而不是批改工夫或者 metadata/build flags)。所以不须要 -a 的编译参数了。
- 和第一条相似,go test 也会正确的 cache 后果。go vet 集成到 go test 调用中。
- 在 pprof 中 blocking 和 mutex 的 profile 文件也自带符号表了。
- Assembler 反对更多的指令(在不同的平台)。
Go 1.11 改变:
- Go mods 首次退出。
- Build 时 cache 默认开启;一些内联函数优化;新引入的包导出格局;switch 的未应用变量查看;
- 链接器反对 AVX512;DEBUG 信息优化;默认压缩的 DWARF 信息;memprof 默认应用 alloc 的 profile;vet 优化;
- Runtime: a sparse heap layout.
- Map 遍历删除和 slice extension 优化。
- 编译器优化:bounds-check and branch elimination, transitive relations; 各种看不懂的优化。
Go 1.12
- 后续不反对 binary library.
- Go doc 和 go vet 代替 godoc 和 go tool vet。
- GC 和内存治理相干的优化。
Go 1.13
- 数字表达方式更改。
- go module 默认行为扭转;GOPRIVATE 环境变量;go get 行为扭转;二进制中蕴含模块版本信息;
- 逃逸剖析改良(重写);
- 批改 Error wrapper 写法.
- 默认应用
MADV_FREE
来向 os 开释内存(会导致 RSS 变高)。
Go 1.14
- overlapping interfaces proposal 嵌入 struct 的重名机制。
- 晋升 defer 性能到简直 0 开销(和间接调用该函数相比)。
- 支流平台上实现 goroutin 的异步抢占?(asynchronously preemptible);零碎调用的时候会减少很多 EINTR 须要本人解决。
- CPU 数量很多的状况下,大块内存并行高频调配时候的缩小锁竞争优化。
- 各种 timer, tick, wait 的优化,缩小锁和上下文切换开销。
- 减少一个 bytes 的 hash 函数。
Go 1.12 – Go 1.14
Go 1.15
- Panic 波及到的变量如果是根底类型派生的,那么把值打进去。
- SIGSEGV, SIGBUS, SIGFPE 会杀掉过程(如果不显式解决的话)。
- 小对象调配优化(在 cpu core 很多的场景下);small int to interface 优化;已敞开的阻塞 / 非阻塞 chan 行为对立。
- 生成的 bin 文件比上个版本小 5%(打消一些 GC 和未应用类型的 metadata);
- unsafe.Pointer 和 uintptr 的转换规则批改;在编译参数中退出缓解 Spectre 破绽影响的选项。
- 链接器大优化(效率和内存应用),是通过新设计的 obj 文件格式和并发某些操作阶段的并发执行带来的。
Go 1.16
- 反对 Apple Silicon。
- 默认应用
go.mod
,带来go install
/go get
等一堆工具的用法批改。 - 能够应用
//go:embed
来嵌入各种文件。 - 用于取代
runtime.ReadMemStats
和debug.GCStats
等运行时接口的runtime/metrics
;Debug 参数inittrace=1
查看启动效率; - 内存开释策略又改成了
MADV_DONTNEED
(在之前的 1.13 版本变更为MADV_FREE
)。 - (接上个版本的)链接器后续优化。
- 文件解决和 io 相干的一些批改, 集中在
io/fs
。
Go 1.17
-
[]T
能够间接转换为[N]T
了。还有一堆新的 unsafe 指针运算。l := []int{1, 2, 3, 4, 5, 6, 7} al := *(*[5]int)(unsafe.Pointer(&l)) // 谬误用法! al2 := *(*[5]int)(unsafe.Pointer(&l[0])) // [1 2 3 4 5] al3 := (*[5]int)(l) // &[1 2 3 4 5]
- 新的 Module graph pruning
这个特色应该叫做依赖关系图修剪?我的了解是:
依赖的库中,跟你的我的项目 (main module) 无关的那些依赖内容,会在go.mod
中标记为// indirect
,而其余的依赖,被称为require directive
。然而为什么要做么做,没有看明确 - 一堆 go mod 相干的行为变动。
- 一种新的函数调用传参形式(应用存放代替栈),进步 5% 的性能,较少 2% 的执行文件容量。利用在 linux/amd64 等最支流体系上。
Go 1.18
- 试验性质的泛型反对。(能力无限,c++ 中的泛型也没搞明确,无奈形容)
- 修复掉长期未解决的一个 bug #8560 (一个非凡场景的申明变量未应用,未被探测到的问题)。
- Fuzzing 反对(貌似是和测试相干的)。
- 一堆 go mod 相干行为变动。
- go workspace 的引入,看起来像是一个 IDE 的工程文件。
- gofmt 工具并发。
- go vet 可能更智能的检测到一些代码写法的问题。
- GC 在评估执行频率的时候思考了不在堆上的资源(例如栈扫描)。
- slice 扩容算法变更(防止渐变?)。
- 1.17 版本的传参优化利用到大部分平台上。这个优化带来的,可能影响堆栈打印不精确的问题,在 1.18 中会标记一个
?
符号。 - 编译速度慢 15%,生成代码的执行速度不变。
- Bootstrapping 的时候,优先应用 Go 1.17(之前是 1.4),而且预报了在 Go 1.19 的时候,须要用 Go 1.17。(这里不得不吐槽一下:说好的都用 Go 1.4 bootstrapping 呢?)
Go 1.19
- 最大的批改:内存模型批改(没看懂)。
- 优化了 go doc 输入文档的格局。如果依照标准书写,go doc 能够输入超链接和列表格局的文档。
- unix build constraint(相似宏)
- 一堆工具小批改:build 参数退出(在
-trimpath
的状况下)、go generate、go env FLAG quotes、go list 输入优化和 cache。 - 加了一个 soft memory limit,查了一下其余的人的说法,看起来是为了防止产生 OOM。
- 超大的 int/string switch 状况下应用 jump table 优化。
正文完