golang快速入門-02
goroutine的并發(fā)數(shù)量
不控制并發(fā)的 goroutine 數(shù)量會發(fā)生什么?
CPU 使用率浮動上漲
Memory 占用不斷上漲
主進程崩潰(被殺掉了)原因是打開文件數(shù)量太多內(nèi)存占用等對系統(tǒng)資源占用過大
解決方案
控制/限制 goroutine 同時并發(fā)運行的數(shù)量
改變應(yīng)用程序的邏輯寫法(避免大規(guī)模的使用系統(tǒng)資源和等待)
使用chan和sync
實現(xiàn)了控制 goroutine 以 2 個 2 個的數(shù)量去執(zhí)行我們的 “業(yè)務(wù)邏輯”
var wg = sync.WaitGroup{}
func main() {
userCount := 10
ch := make(chan bool, 2)
for i := 0; i < userCount; i++ {
wg.Add(1)
go Read(ch, i)
}
wg.Wait()
}
func Read(ch chan bool, i int) {
defer wg.Done()
ch <- true
fmt.Printf("go func: %d, time: %d\n", i, time.Now().Unix())
time.Sleep(time.Second)
<-ch
}
循環(huán)交互賦值是性能分析
常常會遇到循環(huán)交換賦值的數(shù)據(jù)處理場景,尤其是 RPC,數(shù)據(jù)交互格式要轉(zhuǎn)為 Protobuf,賦值是無法避免的。
一般會有如下幾種做法:
for
for range
json.Marshal/Unmarshal
三種做法的性能順序為1 > 2 > 3
for range 在性能上相較 for 差 json。Marsha1最差
for range 始終使用值拷貝的方式來生成循環(huán)變量。通俗來講,就是在每次循環(huán)時,都會對循環(huán)變量重新分配.
encoding/json 標(biāo)準(zhǔn)庫,是通過大量反射來實現(xiàn)的, 因此很慢
總結(jié)
對性能開銷有較高要求:選用 for,開銷最小
中規(guī)中矩:選用 for range,大對象慎用
量小、占用小、數(shù)量可控:選用 json.Marshal/Unmarshal 的方案也可以。其重復(fù)代碼少,但開銷最大
為什么 Go map 遍歷輸出是不固定順序?
for range map 在開始處理循環(huán)邏輯的時候,就做了隨機播種.根據(jù)隨機數(shù),選擇一個桶位置作為起始點進行遍歷迭代.
評論
圖片
表情
