'Go語言回顧:從Go 1.0到Go 1.13'

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

Go語言回顧:從Go 1.0到Go 1.13

Go 1.4 – 2014.12

在該版本中,Go提供了對Android的官方支持。使用golang.org/x/mobile包,gopher們可以使用Go編寫簡單的Android應用。

同時,之前版本中大量用C語言和彙編語言實現的運行時已經被翻譯為Go,一個更為精確的垃圾回收器讓堆內存分配減少了10~30%。

和版本自身無關的是,Go工程在本次發佈後已經從Mercurial遷移到Git,從Google code遷移到github。

Go還發布了go generate命令,該命令可以通過掃碼代碼中的//go:generate指示器來生成代碼,可以幫助Gopher簡化代碼生成工作。

更多關於這方面的信息可以參考Go blog和這篇文章《Generating code》。

Go 1.5 – 2015.8

這個新版本推遲了兩個月發佈,目的是適應Go新的開發發佈週期:每年二月和八月進行發佈:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

Go語言回顧:從Go 1.0到Go 1.13

Go 1.4 – 2014.12

在該版本中,Go提供了對Android的官方支持。使用golang.org/x/mobile包,gopher們可以使用Go編寫簡單的Android應用。

同時,之前版本中大量用C語言和彙編語言實現的運行時已經被翻譯為Go,一個更為精確的垃圾回收器讓堆內存分配減少了10~30%。

和版本自身無關的是,Go工程在本次發佈後已經從Mercurial遷移到Git,從Google code遷移到github。

Go還發布了go generate命令,該命令可以通過掃碼代碼中的//go:generate指示器來生成代碼,可以幫助Gopher簡化代碼生成工作。

更多關於這方面的信息可以參考Go blog和這篇文章《Generating code》。

Go 1.5 – 2015.8

這個新版本推遲了兩個月發佈,目的是適應Go新的開發發佈週期:每年二月和八月進行發佈:

Go語言回顧:從Go 1.0到Go 1.13

圖來自:https://github.com/golang/go/wiki/Go-Release-Cycle

在該版本中,垃圾回收器被全面重構。由於引入併發回收器,回收階段帶來的延遲大幅減少。下面是來自一個生產環境服務器上的延遲數據,我們看到延遲從300ms降到了30ms:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

Go語言回顧:從Go 1.0到Go 1.13

Go 1.4 – 2014.12

在該版本中,Go提供了對Android的官方支持。使用golang.org/x/mobile包,gopher們可以使用Go編寫簡單的Android應用。

同時,之前版本中大量用C語言和彙編語言實現的運行時已經被翻譯為Go,一個更為精確的垃圾回收器讓堆內存分配減少了10~30%。

和版本自身無關的是,Go工程在本次發佈後已經從Mercurial遷移到Git,從Google code遷移到github。

Go還發布了go generate命令,該命令可以通過掃碼代碼中的//go:generate指示器來生成代碼,可以幫助Gopher簡化代碼生成工作。

更多關於這方面的信息可以參考Go blog和這篇文章《Generating code》。

Go 1.5 – 2015.8

這個新版本推遲了兩個月發佈,目的是適應Go新的開發發佈週期:每年二月和八月進行發佈:

Go語言回顧:從Go 1.0到Go 1.13

圖來自:https://github.com/golang/go/wiki/Go-Release-Cycle

在該版本中,垃圾回收器被全面重構。由於引入併發回收器,回收階段帶來的延遲大幅減少。下面是來自一個生產環境服務器上的延遲數據,我們看到延遲從300ms降到了30ms:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://blog.golang.org/ismmkeynote

這個版本還發布go tool trace命令,通過該命令我們可以實現執行器的跟蹤(trace)。這些跟蹤是在test執行、運行時生成的,跟蹤信息可以通過瀏覽器呈現:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

Go語言回顧:從Go 1.0到Go 1.13

Go 1.4 – 2014.12

在該版本中,Go提供了對Android的官方支持。使用golang.org/x/mobile包,gopher們可以使用Go編寫簡單的Android應用。

同時,之前版本中大量用C語言和彙編語言實現的運行時已經被翻譯為Go,一個更為精確的垃圾回收器讓堆內存分配減少了10~30%。

和版本自身無關的是,Go工程在本次發佈後已經從Mercurial遷移到Git,從Google code遷移到github。

Go還發布了go generate命令,該命令可以通過掃碼代碼中的//go:generate指示器來生成代碼,可以幫助Gopher簡化代碼生成工作。

更多關於這方面的信息可以參考Go blog和這篇文章《Generating code》。

Go 1.5 – 2015.8

這個新版本推遲了兩個月發佈,目的是適應Go新的開發發佈週期:每年二月和八月進行發佈:

Go語言回顧:從Go 1.0到Go 1.13

圖來自:https://github.com/golang/go/wiki/Go-Release-Cycle

在該版本中,垃圾回收器被全面重構。由於引入併發回收器,回收階段帶來的延遲大幅減少。下面是來自一個生產環境服務器上的延遲數據,我們看到延遲從300ms降到了30ms:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://blog.golang.org/ismmkeynote

這個版本還發布go tool trace命令,通過該命令我們可以實現執行器的跟蹤(trace)。這些跟蹤是在test執行、運行時生成的,跟蹤信息可以通過瀏覽器呈現:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自原始Go Execution Tracer文檔

Go 1.6 – 2016.2

這個版本的最顯著變化是當使用HTTPS時,將默認支持HTTP/2。

垃圾回收器的延遲在該版本中進一步降低:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

Go語言回顧:從Go 1.0到Go 1.13

Go 1.4 – 2014.12

在該版本中,Go提供了對Android的官方支持。使用golang.org/x/mobile包,gopher們可以使用Go編寫簡單的Android應用。

同時,之前版本中大量用C語言和彙編語言實現的運行時已經被翻譯為Go,一個更為精確的垃圾回收器讓堆內存分配減少了10~30%。

和版本自身無關的是,Go工程在本次發佈後已經從Mercurial遷移到Git,從Google code遷移到github。

Go還發布了go generate命令,該命令可以通過掃碼代碼中的//go:generate指示器來生成代碼,可以幫助Gopher簡化代碼生成工作。

更多關於這方面的信息可以參考Go blog和這篇文章《Generating code》。

Go 1.5 – 2015.8

這個新版本推遲了兩個月發佈,目的是適應Go新的開發發佈週期:每年二月和八月進行發佈:

Go語言回顧:從Go 1.0到Go 1.13

圖來自:https://github.com/golang/go/wiki/Go-Release-Cycle

在該版本中,垃圾回收器被全面重構。由於引入併發回收器,回收階段帶來的延遲大幅減少。下面是來自一個生產環境服務器上的延遲數據,我們看到延遲從300ms降到了30ms:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://blog.golang.org/ismmkeynote

這個版本還發布go tool trace命令,通過該命令我們可以實現執行器的跟蹤(trace)。這些跟蹤是在test執行、運行時生成的,跟蹤信息可以通過瀏覽器呈現:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自原始Go Execution Tracer文檔

Go 1.6 – 2016.2

這個版本的最顯著變化是當使用HTTPS時,將默認支持HTTP/2。

垃圾回收器的延遲在該版本中進一步降低:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

Go 1.7 – 2016.8

這個版本發佈了context包。該包用於處理timeout和取消任務。

更多關於context包的信息,可參考文章:《Context and Cancellation by Propagation》。

編譯器工具鏈的性能得到了較大幅度優化,編譯速度更快,二進制文件size更小,有些時候幅度可達20~30%。

Go 1.8 – 2017.2

垃圾回收器的延遲在該版本中進一步改善,延遲時間已經全面降到毫秒級別以下:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

Go語言回顧:從Go 1.0到Go 1.13

Go 1.4 – 2014.12

在該版本中,Go提供了對Android的官方支持。使用golang.org/x/mobile包,gopher們可以使用Go編寫簡單的Android應用。

同時,之前版本中大量用C語言和彙編語言實現的運行時已經被翻譯為Go,一個更為精確的垃圾回收器讓堆內存分配減少了10~30%。

和版本自身無關的是,Go工程在本次發佈後已經從Mercurial遷移到Git,從Google code遷移到github。

Go還發布了go generate命令,該命令可以通過掃碼代碼中的//go:generate指示器來生成代碼,可以幫助Gopher簡化代碼生成工作。

更多關於這方面的信息可以參考Go blog和這篇文章《Generating code》。

Go 1.5 – 2015.8

這個新版本推遲了兩個月發佈,目的是適應Go新的開發發佈週期:每年二月和八月進行發佈:

Go語言回顧:從Go 1.0到Go 1.13

圖來自:https://github.com/golang/go/wiki/Go-Release-Cycle

在該版本中,垃圾回收器被全面重構。由於引入併發回收器,回收階段帶來的延遲大幅減少。下面是來自一個生產環境服務器上的延遲數據,我們看到延遲從300ms降到了30ms:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://blog.golang.org/ismmkeynote

這個版本還發布go tool trace命令,通過該命令我們可以實現執行器的跟蹤(trace)。這些跟蹤是在test執行、運行時生成的,跟蹤信息可以通過瀏覽器呈現:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自原始Go Execution Tracer文檔

Go 1.6 – 2016.2

這個版本的最顯著變化是當使用HTTPS時,將默認支持HTTP/2。

垃圾回收器的延遲在該版本中進一步降低:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

Go 1.7 – 2016.8

這個版本發佈了context包。該包用於處理timeout和取消任務。

更多關於context包的信息,可參考文章:《Context and Cancellation by Propagation》。

編譯器工具鏈的性能得到了較大幅度優化,編譯速度更快,二進制文件size更小,有些時候幅度可達20~30%。

Go 1.8 – 2017.2

垃圾回收器的延遲在該版本中進一步改善,延遲時間已經全面降到毫秒級別以下:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

對延遲的優化還將繼續。接下來版本的目標是將延遲降到100微秒左右。

這個版本還大幅提升了defer的性能:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

Go語言回顧:從Go 1.0到Go 1.13

Go 1.4 – 2014.12

在該版本中,Go提供了對Android的官方支持。使用golang.org/x/mobile包,gopher們可以使用Go編寫簡單的Android應用。

同時,之前版本中大量用C語言和彙編語言實現的運行時已經被翻譯為Go,一個更為精確的垃圾回收器讓堆內存分配減少了10~30%。

和版本自身無關的是,Go工程在本次發佈後已經從Mercurial遷移到Git,從Google code遷移到github。

Go還發布了go generate命令,該命令可以通過掃碼代碼中的//go:generate指示器來生成代碼,可以幫助Gopher簡化代碼生成工作。

更多關於這方面的信息可以參考Go blog和這篇文章《Generating code》。

Go 1.5 – 2015.8

這個新版本推遲了兩個月發佈,目的是適應Go新的開發發佈週期:每年二月和八月進行發佈:

Go語言回顧:從Go 1.0到Go 1.13

圖來自:https://github.com/golang/go/wiki/Go-Release-Cycle

在該版本中,垃圾回收器被全面重構。由於引入併發回收器,回收階段帶來的延遲大幅減少。下面是來自一個生產環境服務器上的延遲數據,我們看到延遲從300ms降到了30ms:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://blog.golang.org/ismmkeynote

這個版本還發布go tool trace命令,通過該命令我們可以實現執行器的跟蹤(trace)。這些跟蹤是在test執行、運行時生成的,跟蹤信息可以通過瀏覽器呈現:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自原始Go Execution Tracer文檔

Go 1.6 – 2016.2

這個版本的最顯著變化是當使用HTTPS時,將默認支持HTTP/2。

垃圾回收器的延遲在該版本中進一步降低:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

Go 1.7 – 2016.8

這個版本發佈了context包。該包用於處理timeout和取消任務。

更多關於context包的信息,可參考文章:《Context and Cancellation by Propagation》。

編譯器工具鏈的性能得到了較大幅度優化,編譯速度更快,二進制文件size更小,有些時候幅度可達20~30%。

Go 1.8 – 2017.2

垃圾回收器的延遲在該版本中進一步改善,延遲時間已經全面降到毫秒級別以下:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

對延遲的優化還將繼續。接下來版本的目標是將延遲降到100微秒左右。

這個版本還大幅提升了defer的性能:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://medium.com/@blanchon.vincent/go-how-does-defer-statement-work-1a9492689b6e

更多關於defer的信息,可以參考文章How Does Defer statement Work?。

Go 1.9 – 2017.8

該版本引入了alias語法。

type byte = uint8

這裡byte是unit8的一個alias。

sync包增加了Map類型,該類型支持併發訪問(原生map類型不支持)。

關於map的更多信息,參考文章“Concurrency Access with Maps”。

Go 1.10 – 2018.2

在該版本中,test包引入了一個新的緩存機制,所有通過測試的結果都將被緩存下來。當test沒有變化時,重複執行test會節省大量運行test的時間。

first run:
ok /go/src/retro 0.027s
second run:
ok /go/src/retro (cached)

go build命令也維護了一個已構建的包的緩存以加速構建性能。

該版本中垃圾回收器並沒有顯著性能提升。但是Go team為垃圾回收定義了一個新的SLO(Service-Level Objective):

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

Go語言回顧:從Go 1.0到Go 1.13

Go 1.4 – 2014.12

在該版本中,Go提供了對Android的官方支持。使用golang.org/x/mobile包,gopher們可以使用Go編寫簡單的Android應用。

同時,之前版本中大量用C語言和彙編語言實現的運行時已經被翻譯為Go,一個更為精確的垃圾回收器讓堆內存分配減少了10~30%。

和版本自身無關的是,Go工程在本次發佈後已經從Mercurial遷移到Git,從Google code遷移到github。

Go還發布了go generate命令,該命令可以通過掃碼代碼中的//go:generate指示器來生成代碼,可以幫助Gopher簡化代碼生成工作。

更多關於這方面的信息可以參考Go blog和這篇文章《Generating code》。

Go 1.5 – 2015.8

這個新版本推遲了兩個月發佈,目的是適應Go新的開發發佈週期:每年二月和八月進行發佈:

Go語言回顧:從Go 1.0到Go 1.13

圖來自:https://github.com/golang/go/wiki/Go-Release-Cycle

在該版本中,垃圾回收器被全面重構。由於引入併發回收器,回收階段帶來的延遲大幅減少。下面是來自一個生產環境服務器上的延遲數據,我們看到延遲從300ms降到了30ms:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://blog.golang.org/ismmkeynote

這個版本還發布go tool trace命令,通過該命令我們可以實現執行器的跟蹤(trace)。這些跟蹤是在test執行、運行時生成的,跟蹤信息可以通過瀏覽器呈現:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自原始Go Execution Tracer文檔

Go 1.6 – 2016.2

這個版本的最顯著變化是當使用HTTPS時,將默認支持HTTP/2。

垃圾回收器的延遲在該版本中進一步降低:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

Go 1.7 – 2016.8

這個版本發佈了context包。該包用於處理timeout和取消任務。

更多關於context包的信息,可參考文章:《Context and Cancellation by Propagation》。

編譯器工具鏈的性能得到了較大幅度優化,編譯速度更快,二進制文件size更小,有些時候幅度可達20~30%。

Go 1.8 – 2017.2

垃圾回收器的延遲在該版本中進一步改善,延遲時間已經全面降到毫秒級別以下:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

對延遲的優化還將繼續。接下來版本的目標是將延遲降到100微秒左右。

這個版本還大幅提升了defer的性能:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://medium.com/@blanchon.vincent/go-how-does-defer-statement-work-1a9492689b6e

更多關於defer的信息,可以參考文章How Does Defer statement Work?。

Go 1.9 – 2017.8

該版本引入了alias語法。

type byte = uint8

這裡byte是unit8的一個alias。

sync包增加了Map類型,該類型支持併發訪問(原生map類型不支持)。

關於map的更多信息,參考文章“Concurrency Access with Maps”。

Go 1.10 – 2018.2

在該版本中,test包引入了一個新的緩存機制,所有通過測試的結果都將被緩存下來。當test沒有變化時,重複執行test會節省大量運行test的時間。

first run:
ok /go/src/retro 0.027s
second run:
ok /go/src/retro (cached)

go build命令也維護了一個已構建的包的緩存以加速構建性能。

該版本中垃圾回收器並沒有顯著性能提升。但是Go team為垃圾回收定義了一個新的SLO(Service-Level Objective):

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

Go 1.11 – 2018.8

Go 1.11引入了一個重要的新功能:Go modules。Go module的引入是為了應對過去幾年官方調查問卷結果中Go社區反饋的幾個主要挑戰:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

Go語言回顧:從Go 1.0到Go 1.13

Go 1.4 – 2014.12

在該版本中,Go提供了對Android的官方支持。使用golang.org/x/mobile包,gopher們可以使用Go編寫簡單的Android應用。

同時,之前版本中大量用C語言和彙編語言實現的運行時已經被翻譯為Go,一個更為精確的垃圾回收器讓堆內存分配減少了10~30%。

和版本自身無關的是,Go工程在本次發佈後已經從Mercurial遷移到Git,從Google code遷移到github。

Go還發布了go generate命令,該命令可以通過掃碼代碼中的//go:generate指示器來生成代碼,可以幫助Gopher簡化代碼生成工作。

更多關於這方面的信息可以參考Go blog和這篇文章《Generating code》。

Go 1.5 – 2015.8

這個新版本推遲了兩個月發佈,目的是適應Go新的開發發佈週期:每年二月和八月進行發佈:

Go語言回顧:從Go 1.0到Go 1.13

圖來自:https://github.com/golang/go/wiki/Go-Release-Cycle

在該版本中,垃圾回收器被全面重構。由於引入併發回收器,回收階段帶來的延遲大幅減少。下面是來自一個生產環境服務器上的延遲數據,我們看到延遲從300ms降到了30ms:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://blog.golang.org/ismmkeynote

這個版本還發布go tool trace命令,通過該命令我們可以實現執行器的跟蹤(trace)。這些跟蹤是在test執行、運行時生成的,跟蹤信息可以通過瀏覽器呈現:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自原始Go Execution Tracer文檔

Go 1.6 – 2016.2

這個版本的最顯著變化是當使用HTTPS時,將默認支持HTTP/2。

垃圾回收器的延遲在該版本中進一步降低:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

Go 1.7 – 2016.8

這個版本發佈了context包。該包用於處理timeout和取消任務。

更多關於context包的信息,可參考文章:《Context and Cancellation by Propagation》。

編譯器工具鏈的性能得到了較大幅度優化,編譯速度更快,二進制文件size更小,有些時候幅度可達20~30%。

Go 1.8 – 2017.2

垃圾回收器的延遲在該版本中進一步改善,延遲時間已經全面降到毫秒級別以下:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

對延遲的優化還將繼續。接下來版本的目標是將延遲降到100微秒左右。

這個版本還大幅提升了defer的性能:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://medium.com/@blanchon.vincent/go-how-does-defer-statement-work-1a9492689b6e

更多關於defer的信息,可以參考文章How Does Defer statement Work?。

Go 1.9 – 2017.8

該版本引入了alias語法。

type byte = uint8

這裡byte是unit8的一個alias。

sync包增加了Map類型,該類型支持併發訪問(原生map類型不支持)。

關於map的更多信息,參考文章“Concurrency Access with Maps”。

Go 1.10 – 2018.2

在該版本中,test包引入了一個新的緩存機制,所有通過測試的結果都將被緩存下來。當test沒有變化時,重複執行test會節省大量運行test的時間。

first run:
ok /go/src/retro 0.027s
second run:
ok /go/src/retro (cached)

go build命令也維護了一個已構建的包的緩存以加速構建性能。

該版本中垃圾回收器並沒有顯著性能提升。但是Go team為垃圾回收定義了一個新的SLO(Service-Level Objective):

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

Go 1.11 – 2018.8

Go 1.11引入了一個重要的新功能:Go modules。Go module的引入是為了應對過去幾年官方調查問卷結果中Go社區反饋的幾個主要挑戰:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://blog.golang.org/survey2018-results

另外一個重要功能是一個試驗功能:支持WebAssembly。允許開發人員將Go源碼編譯成一個兼容四個主流瀏覽器的二進制格式文件。

Go 1.12 – 2019.2

該版本中,go vet基於analysis包進行了重寫,使得go vet更為靈活並支持Go開發人員編寫自己的checker。

更多關於analyzer的信息可以參考文章《How to Build Your Own Analyzer》。

Go 1.13 – 2019.9

在該版本中,sync.Pool得到了改善:當垃圾回收時,pool中對象不會被完全清理掉。它引入了一個cache,用於在兩次GC之前清理pool中未使用的對象實例。

逃逸分析(escape analysis)被重新實現了,在該版本中,Go得意更少地在堆上分配內存了。下面是新舊逃逸分析的基準測試對比:

"

Go 1.13版本在2019.9.3正式發佈!國外的Gopher Vincent Blanchon發表了一篇文章《Go: Retrospective》(科學上網閱讀),對Go從1.0版本到1.13版本做了簡要的回顧,這裡是那篇文章的譯文。

Go語言回顧:從Go 1.0到Go 1.13

對於每一位Go開發者來說,Go語言的演化歷程是必須要知道的事情。瞭解這些橫跨年份發佈的大版本的主要變化將有助於Gopher理解Go語言的發展理念以及該語言每個版本的優勢與不足。更多關於特定版本的變更細節,可以參考每個版本對應的Changelog。

Go 1.0 – 2012.3月

伴隨著Go語言的第一個版本,Go的締造者還發布了一份兼容性文檔。該文檔保證未來的Go版本將保持向後兼容性(backward-compatible),即始終兼容已有的代碼,保證已有代碼在Go新版本下編譯和運行的正確性。

Go 1.0版本還包含了go tool pprof命令,這是一個Google pprof C++ profiler的變體。Go 1.0還提供了go vet命令(之前的go tool vet),用於報告Go package中可能的錯誤。

Go 1.1 – 2013.5月

該版本主要專注於語言改善和性能提升(編譯器、垃圾回收、map、goroutine調度)。這裡是一個改善後的效果示意圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自https://dave.cheney.net/2013/05/21/go-11-performance-improvements

這個版本同時還嵌入了一個競態探測器(race detector),這個工具對於Go這種原生併發的語言是十分必要的。在《Race Detector with ThreadSanitizer”》一文中,你可以找到有關race detector的更多詳細信息。

在這個版本中的一個重點變動是Goroutine調度器被重寫了,重寫後的調度器性能大幅提升。

重寫後的Go調度器的設計如下圖:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

M對應的是操作系統的線程。P表示一個處理器(P的數量不能超過GOMAXPROCS),每個P擁有一個本地goroutine隊列。在1.1版本之前,P這個抽象並不存在。所有goroutine的調度通過全局互斥鎖進行全局級別的管理。這次改進實現了”work-stealing”算法,允許某個P從其他P的隊列中”偷goroutine”:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://rakyll.org/scheduler/

更多關於Go調度器調度原理以及”work-stealing”算法的信息,可以查看Jaana B. Dogan的文章《Go’s work-stealing scheduler》。

Go 1.2 – 2013.12

在該版本中,Go test命令開始支持代碼測試覆蓋率統計了,並且通過go提供的新子命令: go tool cover可以查看代碼測試覆蓋率統計信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

它還能提供代碼覆蓋信息:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 https://blog.golang.org/cover

Go 1.3 – 2014.6

該版本包含了棧管理的一個重要改進。在該版本中,棧內存分配採用連續段(contiguous segment)的分配模式以提升內存分配效率。這將為下一個版本將棧size降到2KB奠定基礎。之前的分割棧分配方式(segment stack)存在頻繁分配/釋放棧段導致棧內存分配性能不穩定(較低)的問題,引入新機制後,分配穩定性和性能都有較大改善。

這裡是一個json包的例子,圖中顯示json包對棧size的敏感度:

Go語言回顧:從Go 1.0到Go 1.13

圖來自 contiguous stack

使用連續段的棧內存分配管理模式解決了一些程序性能低下的問題。下面是html/template包的性能對stack size的敏感度圖:

Go語言回顧:從Go 1.0到Go 1.13

更多信息可參見[《How Does the Goroutine Stack Size Evolve?”》(https://medium.com/@blanchon.vincent/go-how-does-the-goroutine-stack-size-evolve-447fc02085e5)]。

這個版本還發布了sync.Pool。這個組件允許我們後面重用結構體,減少內存分配的次數。它也將成為Go生態圈中許多性能提升的源頭,比如:標準庫中的encoding/json、net/http或是Go社區中的zap等。

關於sync.Pool的更多信息,可以參考文章《Understand the Design of Sync.Pool》。

Go開發組在該版本中對channel進行了優化改善,使其性能獲得提升。下面是channel在Go 1.2和Go 1.3版本中的基準測試數據對比:

Go語言回顧:從Go 1.0到Go 1.13

Go 1.4 – 2014.12

在該版本中,Go提供了對Android的官方支持。使用golang.org/x/mobile包,gopher們可以使用Go編寫簡單的Android應用。

同時,之前版本中大量用C語言和彙編語言實現的運行時已經被翻譯為Go,一個更為精確的垃圾回收器讓堆內存分配減少了10~30%。

和版本自身無關的是,Go工程在本次發佈後已經從Mercurial遷移到Git,從Google code遷移到github。

Go還發布了go generate命令,該命令可以通過掃碼代碼中的//go:generate指示器來生成代碼,可以幫助Gopher簡化代碼生成工作。

更多關於這方面的信息可以參考Go blog和這篇文章《Generating code》。

Go 1.5 – 2015.8

這個新版本推遲了兩個月發佈,目的是適應Go新的開發發佈週期:每年二月和八月進行發佈:

Go語言回顧:從Go 1.0到Go 1.13

圖來自:https://github.com/golang/go/wiki/Go-Release-Cycle

在該版本中,垃圾回收器被全面重構。由於引入併發回收器,回收階段帶來的延遲大幅減少。下面是來自一個生產環境服務器上的延遲數據,我們看到延遲從300ms降到了30ms:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://blog.golang.org/ismmkeynote

這個版本還發布go tool trace命令,通過該命令我們可以實現執行器的跟蹤(trace)。這些跟蹤是在test執行、運行時生成的,跟蹤信息可以通過瀏覽器呈現:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自原始Go Execution Tracer文檔

Go 1.6 – 2016.2

這個版本的最顯著變化是當使用HTTPS時,將默認支持HTTP/2。

垃圾回收器的延遲在該版本中進一步降低:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

Go 1.7 – 2016.8

這個版本發佈了context包。該包用於處理timeout和取消任務。

更多關於context包的信息,可參考文章:《Context and Cancellation by Propagation》。

編譯器工具鏈的性能得到了較大幅度優化,編譯速度更快,二進制文件size更小,有些時候幅度可達20~30%。

Go 1.8 – 2017.2

垃圾回收器的延遲在該版本中進一步改善,延遲時間已經全面降到毫秒級別以下:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

對延遲的優化還將繼續。接下來版本的目標是將延遲降到100微秒左右。

這個版本還大幅提升了defer的性能:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://medium.com/@blanchon.vincent/go-how-does-defer-statement-work-1a9492689b6e

更多關於defer的信息,可以參考文章How Does Defer statement Work?。

Go 1.9 – 2017.8

該版本引入了alias語法。

type byte = uint8

這裡byte是unit8的一個alias。

sync包增加了Map類型,該類型支持併發訪問(原生map類型不支持)。

關於map的更多信息,參考文章“Concurrency Access with Maps”。

Go 1.10 – 2018.2

在該版本中,test包引入了一個新的緩存機制,所有通過測試的結果都將被緩存下來。當test沒有變化時,重複執行test會節省大量運行test的時間。

first run:
ok /go/src/retro 0.027s
second run:
ok /go/src/retro (cached)

go build命令也維護了一個已構建的包的緩存以加速構建性能。

該版本中垃圾回收器並沒有顯著性能提升。但是Go team為垃圾回收定義了一個新的SLO(Service-Level Objective):

Go語言回顧:從Go 1.0到Go 1.13

圖片來自https://blog.golang.org/ismmkeynote

Go 1.11 – 2018.8

Go 1.11引入了一個重要的新功能:Go modules。Go module的引入是為了應對過去幾年官方調查問卷結果中Go社區反饋的幾個主要挑戰:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://blog.golang.org/survey2018-results

另外一個重要功能是一個試驗功能:支持WebAssembly。允許開發人員將Go源碼編譯成一個兼容四個主流瀏覽器的二進制格式文件。

Go 1.12 – 2019.2

該版本中,go vet基於analysis包進行了重寫,使得go vet更為靈活並支持Go開發人員編寫自己的checker。

更多關於analyzer的信息可以參考文章《How to Build Your Own Analyzer》。

Go 1.13 – 2019.9

在該版本中,sync.Pool得到了改善:當垃圾回收時,pool中對象不會被完全清理掉。它引入了一個cache,用於在兩次GC之前清理pool中未使用的對象實例。

逃逸分析(escape analysis)被重新實現了,在該版本中,Go得意更少地在堆上分配內存了。下面是新舊逃逸分析的基準測試對比:

Go語言回顧:從Go 1.0到Go 1.13

圖片來自 https://github.com/golang/go/issues/23109


英文原文鏈接:https://medium.com/a-journey-with-go/go-retrospective-b9723352e9b0

譯文鏈接:https://tonybai.com/2019/09/07/go-retrospective/

本文譯者:tony bai,bigwhite. 版權所有.

"

相關推薦

推薦中...