Golang 將改變常見的 closure 地雷

在「Fixing for loops in Go 1.22 (go.dev)」看到的,原文在「Fixing For Loops in Go 1.22」這邊。

算是各種有 closure 的程式語言會遇到的經典問題,下面的 Golang 程式在撰寫時會預期輸出 abc (不保證順序),但實際上會輸出 ccc,因為變數的 scope 設計原因:

func main() {
    done := make(chan bool)

    values := []string{"a", "b", "c"}
    for _, v := range values {
        go func() {
            fmt.Println(v)
            done <- true
        }()
    }

    // wait for all goroutines to complete before exiting
    for _ = range values {
        <-done
    }
}

這在 JavaScript 也是個經典的問題,搜「javascript closure loop」就可以看到「JavaScript closure inside loops – simple practical example」這個例子,對應的答案則是有提到 ES6let 因為改變了變數的 scope,可以用來解決這個問題。

剛好 let 也是 best practice 了,所以現在 JavaScript 這邊遇到這個問題的情況會少一些。

回到 Golang 這邊,Golang 是打算改變在 for loop 時,對應變數的 scope 來解決:

For Go 1.22, we plan to change for loops to make these variables have per-iteration scope instead of per-loop scope. This change will fix the examples above, so that they are no longer buggy Go programs; it will end the production problems caused by such mistakes; and it will remove the need for imprecise tools that prompt users to make unnecessary changes to their code.

另外因為這是 breaking compatibility 的改變 (畢竟有些程式碼是清楚知道這個特性而刻意這樣寫的),所以會有對應的措施,只有在有指定 Golang 1.22 或是更新的版本才會用新的 scope 編譯:

To ensure backwards compatibility with existing code, the new semantics will only apply in packages contained in modules that declare go 1.22 or later in their go.mod files. This per-module decision provides developer control of a gradual update to the new semantics throughout a codebase. It is also possible to use //go:build lines to control the decision on a per-file basis.

Netflix 的 FrameScope,將效能資料轉成 2D 圖片

Netflix 丟出了 FlameScope,另外一種顯示效能的工具,將效能資料轉成 2D 圖片:「Netflix FlameScope」。

We’re excited to release FlameScope: a new performance visualization tool for analyzing variance, perturbations, single-threaded execution, application startup, and other time-based issues.

然後這個工具同樣是發明火焰圖的 Brendan Gregg 與他的同事 Martin Spier 的作品:

FlameScope was developed by Martin Spier and Brendan Gregg, Netflix cloud performance engineering team. Blog post by Brendan Gregg.

火焰圖 (flame graph) 就是這個:

這次推出的是這樣的圖:

其實是每秒切一次 offset 做出來的圖:

就可以很簡單的看出來哪些區塊以及 pattern 是熱點: