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 现在允许嵌入具有重叠方法集的接口:来自嵌入式接口的方法可能具有与(嵌入)接口中已有的方法相同的名称和相同的签名。这解决了菱形的嵌入图通常(但不是完全)发生的问题。接口中显式声明的方法必须像以前一样保持唯一。

示例:

  1. type ReadWriteCloser interface {
  2. io.ReadCloser
  3. io.WriteCloser
  4. }

此处在Go1.14版本以前是错误的,因为它将相同方法添加到接口两次,打破了唯一性约束。Close

报错信息:duplicate method Close

性能提升

1、defer性能提升

与直接调用延迟函数相比,此版本提高了大多数使用 的性能,产生开销几乎为零。因此,现在可用于性能关键型代码,而无需担心开销问题。如下为go1.14.4和go1.13.3 基准测试结果对比。

创建文件defer_test.go

go version go1.14.4

  1. # go test -bench=. -v
  2. goos: linux
  3. goarch: amd64
  4. BenchmarkNoDefer
  5. BenchmarkNoDefer 20285859 58.1 ns/op
  6. BenchmarkDefer
  7. BenchmarkDefer 20234445 59.3 ns/op
  8. PASS
  9. ok _/var/www 2.502s

go version go1.13.3

  1. $ go test -bench=. -v
  2. goos: windows
  3. goarch: amd64
  4. pkg: demo
  5. BenchmarkNoDefer-4 8218705 185 ns/op
  6. BenchmarkDefer-4 4724139 247 ns/op
  7. PASS
  8. 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数据,数据来源

  1. https://github.com/golang/go/commit/6becb033341602f2df9d7c55cc23e64b925bbee2
  1. runtime: switch to using new timer code
  2. No big changes in the runtime package benchmarks.
  3. Changes in the time package benchmarks:
  4. name old time/op new time/op delta
  5. AfterFunc-12 1.57ms ± 1% 0.07ms ± 1% -95.42% (p=0.000 n=10+8)
  6. After-12 1.63ms ± 3% 0.11ms ± 1% -93.54% (p=0.000 n=9+10)
  7. Stop-12 78.3µs ± 3% 73.6µs ± 3% -6.01% (p=0.000 n=9+10)
  8. SimultaneousAfterFunc-12 138µs ± 1% 111µs ± 1% -19.57% (p=0.000 n=10+9)
  9. StartStop-12 28.7µs ± 1% 31.5µs ± 5% +9.64% (p=0.000 n=10+7)
  10. Reset-12 6.78µs ± 1% 4.24µs ± 7% -37.45% (p=0.000 n=9+10)
  11. Sleep-12 183µs ± 1% 125µs ± 1% -31.67% (p=0.000 n=10+9)
  12. Ticker-12 5.40ms ± 2% 0.03ms ± 1% -99.43% (p=0.000 n=10+10)
  13. Sub-12 114ns ± 1% 113ns ± 3% ~ (p=0.069 n=9+10)
  14. Now-12 37.2ns ± 1% 36.8ns ± 3% ~ (p=0.287 n=8+8)
  15. NowUnixNano-12 38.1ns ± 2% 37.4ns ± 3% -1.87% (p=0.020 n=10+9)
  16. Format-12 252ns ± 2% 195ns ± 3% -22.61% (p=0.000 n=9+10)
  17. FormatNow-12 234ns ± 1% 177ns ± 2% -24.34% (p=0.000 n=10+10)
  18. MarshalJSON-12 320ns ± 2% 250ns ± 0% -21.94% (p=0.000 n=8+8)
  19. MarshalText-12 320ns ± 2% 245ns ± 2% -23.30% (p=0.000 n=9+10)
  20. Parse-12 206ns ± 2% 208ns ± 4% ~ (p=0.084 n=10+10)
  21. ParseDuration-12 89.1ns ± 1% 86.6ns ± 3% -2.78% (p=0.000 n=10+10)
  22. Hour-12 4.43ns ± 2% 4.46ns ± 1% ~ (p=0.324 n=10+8)
  23. Second-12 4.47ns ± 1% 4.40ns ± 3% ~ (p=0.145 n=9+10)
  24. Year-12 14.6ns ± 1% 14.7ns ± 2% ~ (p=0.112 n=9+9)
  25. 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://golang.org/doc/go1.14

https://studygolang.com/articles/26529

links

  • 目录
  • 上一节:
  • 下一节: