簡介
最新的 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