- 儘量避免使用defer
- Go 性能分析大法: 遇到需要優化程序的時候上Go pprof
- Context
- range 循環例遍
跟著我學習Go語言 這是第五天了, 我們來稍微深入一下. 上面三個是基本規範
儘量避免使用defer
什麼是defer, 為什麼儘量避免,希望大家順著我的提示去深入瞭解.這樣學習,體會會更深.學的也紮實
什麼是defer 先來看看個例子。例defer:
<code>func
f
()
(result
int
) {defer
func
()
{ result++ }()return
0
}/<code>
本意是函數退出之前保證執行一下的工作一般.這樣 但是defer 一般都使用到了閉包. 還有內部鏈表結構. 對應內存消耗.資源消耗.go 1.14之前是非常慢的.
當日2.25日發佈的go 1.14版本徹底改變了這個歷史. 性能基本與無defer 差不多了.
Go 性能分析大法: 遇到需要優化程序的時候上Go pprof
當遇到程序佔用很多內存或者cpu的時候 這個時候需要使用Go pprof 性能分析工具.
一個是對普通應用程序分析的庫 runtime/pprof
另外一個是net/http/pprof
生成一個性能圖樹形結構. 可有詳細每個10ms 收集一下數據. 分析到底哪裡程序慢了.
然後在對應做優化.
Context
Conext 是go程序一個非常關鍵的上下文結構, 學習go一定要學好 Context. 這裡引申一下. 具體的後面會詳細講解.
我們實戰工程中一般在main 主程序建立 ctx, Cancel := context.WithCancel(context.Background())
父親context 然後一路傳遞到各個協程(Goroutine)
子協程一接收到這個上下文. 當外面kill 主程序的時候.子協程也就收到canncel 信號,退出了
避免內存洩露 很多上面pprof 都是優化這裡的.如果你明白這個就減少pprof 呵呵...
<code>func
(ctx
context
.Context
,...) {out
:=make
(channel...) gofunc
() { select { case ctx.Done
(): return case .... } }() }/<code>
Range 循環
<code>package
mainimport
"fmt"
func
main
()
{ nums := []int
{2
,3
,4
} sum :=0
for
_, num :=range
nums { sum += num } fmt.Println("sum:"
, sum)for
i, num :=range
nums {if
num ==3
{ fmt.Println("index:"
, i) } } kvs :=map
[string
]string
{"a"
:"apple"
,"b"
:"banana"
}for
k, v :=range
kvs { fmt.Printf("%s -> %s\n"
, k, v) }for
i, c :=range
"go"
{ fmt.Println(i, c) } }/<code>