13.1 Go1.14版本 新特性
简介
最新的 Go 版本 1.14 在 Go 1.13 之后六个月到达。它的主要更改是工具链、运行时和库的实现。该版本一如既往保持 Go 1的兼容性承诺。我们预计几乎所有的 Go 程序都能够继续编译和运行。
Go Module已经具备生产环境中使用条件了,我们鼓励所有用户迁移到Go Module进行依赖项管理。如果您由于 Go 工具链中的问题而无法迁移,请确保问题已提交 open issue(如果问题不在go``Go1.15
,请让我们知道为什么它阻止您迁移,以便我们可以适当地确定其优先级。
语言更改
根据重叠接口建议,Go 1.14 现在允许嵌入具有重叠方法集的接口:来自嵌入式接口的方法可能具有与(嵌入)接口中已有的方法相同的名称和相同的签名。这解决了菱形的嵌入图通常(但不是完全)发生的问题。接口中显式声明的方法必须像以前一样保持唯一。
示例:
type ReadWriteCloser interface {
io.ReadCloser
io.WriteCloser
}
此处在Go1.14版本以前是错误的,因为它将相同方法添加到接口两次,打破了唯一性约束。Close
报错信息:duplicate method Close
性能提升
1、defer性能提升
与直接调用延迟函数相比,此版本提高了大多数使用 的性能,产生开销几乎为零。因此,现在可用于性能关键型代码,而无需担心开销问题。如下为go1.14.4和go1.13.3 基准测试结果对比。
创建文件defer_test.go
go version go1.14.4
# go test -bench=. -v
goos: linux
goarch: amd64
BenchmarkNoDefer
BenchmarkNoDefer 20285859 58.1 ns/op
BenchmarkDefer
BenchmarkDefer 20234445 59.3 ns/op
PASS
ok _/var/www 2.502s
go version go1.13.3
$ go test -bench=. -v
goos: windows
goarch: amd64
pkg: demo
BenchmarkNoDefer-4 8218705 185 ns/op
BenchmarkDefer-4 4724139 247 ns/op
PASS
ok demo 3.985s
通过如上对比我们发现go version go1.14.4 下,使用defer和不使用defer性能相差无几。
2、goroutine 支持异步抢占
在go1.12版本以前,调度器只能依靠 goroutine 主动让出 CPU 资源,这样存在非常严重的调度问题:
设想一下,假如一个goroutine陷入死循环,它会一直占用系统资源,会导致调度器延时和垃圾回收延时。
垃圾回收需要暂停整个程序(Stop-the-world,STW),如果没有抢占可能需要等待几分钟的时间,导致整个程序无法工作
在go1.12版本中,采用一个非协作式的抢占技术, 来允许对很长的循环进行抢占。在特定时机插入函数,通过函数调用作为入口触发抢占,实现了协作式的抢占式调度。这种抢占方式并不是强制发生的,不会使一个没有主动放弃执行权、且不参与任何函数调用的goroutine被抢占。
在go1.14版本中,引入了基于系统信号的异步抢占调度,这样,像上面的无函数调用的死循环 goroutine 也可以被抢占了,不过代价是出现死循环导致的性能下降问题更难排查了。
4、time.Timer定时器性能得到“巨幅”提升
先看一下官方的benchmark数据,数据来源
https://github.com/golang/go/commit/6becb033341602f2df9d7c55cc23e64b925bbee2
runtime: switch to using new timer code
No big changes in the runtime package benchmarks.
Changes in the time package benchmarks:
name old time/op new time/op delta
AfterFunc-12 1.57ms ± 1% 0.07ms ± 1% -95.42% (p=0.000 n=10+8)
After-12 1.63ms ± 3% 0.11ms ± 1% -93.54% (p=0.000 n=9+10)
Stop-12 78.3µs ± 3% 73.6µs ± 3% -6.01% (p=0.000 n=9+10)
SimultaneousAfterFunc-12 138µs ± 1% 111µs ± 1% -19.57% (p=0.000 n=10+9)
StartStop-12 28.7µs ± 1% 31.5µs ± 5% +9.64% (p=0.000 n=10+7)
Reset-12 6.78µs ± 1% 4.24µs ± 7% -37.45% (p=0.000 n=9+10)
Sleep-12 183µs ± 1% 125µs ± 1% -31.67% (p=0.000 n=10+9)
Ticker-12 5.40ms ± 2% 0.03ms ± 1% -99.43% (p=0.000 n=10+10)
Sub-12 114ns ± 1% 113ns ± 3% ~ (p=0.069 n=9+10)
Now-12 37.2ns ± 1% 36.8ns ± 3% ~ (p=0.287 n=8+8)
NowUnixNano-12 38.1ns ± 2% 37.4ns ± 3% -1.87% (p=0.020 n=10+9)
Format-12 252ns ± 2% 195ns ± 3% -22.61% (p=0.000 n=9+10)
FormatNow-12 234ns ± 1% 177ns ± 2% -24.34% (p=0.000 n=10+10)
MarshalJSON-12 320ns ± 2% 250ns ± 0% -21.94% (p=0.000 n=8+8)
MarshalText-12 320ns ± 2% 245ns ± 2% -23.30% (p=0.000 n=9+10)
Parse-12 206ns ± 2% 208ns ± 4% ~ (p=0.084 n=10+10)
ParseDuration-12 89.1ns ± 1% 86.6ns ± 3% -2.78% (p=0.000 n=10+10)
Hour-12 4.43ns ± 2% 4.46ns ± 1% ~ (p=0.324 n=10+8)
Second-12 4.47ns ± 1% 4.40ns ± 3% ~ (p=0.145 n=9+10)
Year-12 14.6ns ± 1% 14.7ns ± 2% ~ (p=0.112 n=9+9)
Day-12 20.1ns ± 3% 20.2ns ± 1% ~ (p=0.404 n=10+9)
5、Go 1.14 test 优化
go test -v 现在将 t.Log 输出流式传输,而不是在所有测试数据结束时输出。
testing 包的 T、B 和 TB 都加上了 CleanUp 方法,主要作用可以用来测试结束后清理资源。
6、其他特性
- 添加了新包hash/maphash
- WebAssembly的变化
- reflect包的变化
- 工具的变化
参考资料
https://studygolang.com/articles/26529
links
- 目录
- 上一节:
- 下一节: