七叶笔记 » golang编程 » 围观Go1.14版本 新特性

围观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数据,数据来源

   
 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包的变化
  • 工具的变化

参考资料

相关文章