對于一些初學者村生,自知道 Go 里面的 array 以 pass-by-value 方式傳遞后,就莫名地引起 “恐慌”饼丘。外加諸多文章未作說明趁桃,就建議用 slice 代替 array,企圖避免數(shù)據(jù)拷貝葬毫,提升性能镇辉。實際上,此做法有待商榷贴捡。某些時候怕會適得其反,倒造成不必要的性能損失村砂。
用個簡單的示例說明烂斋。
代碼很簡單,兩個函數(shù)分別返回 “內(nèi)容相同” 的 array 和 slice础废。為避免編譯器優(yōu)化汛骂,特填充了全部數(shù)據(jù),以模擬 “真實” 數(shù)據(jù)復制行為评腺。接下來帘瞭,看看性能測試對比。
這結(jié)果怕是顛覆了最初認知蒿讥。array 非但擁有更好的性能蝶念,還避免了堆內(nèi)存分配,也就是說減輕了 GC 壓力芋绸。為什么會這樣媒殉?
熟悉匯編的,怕是很容易看出來摔敛。函數(shù) array 返回值的復制只需用 "CX + REP" 指令就可完成廷蓉。
整個 array 函數(shù)完全在棧上完成,而 slice 函數(shù)則需執(zhí)行 makeslice马昙,繼而在堆上分配內(nèi)存桃犬,這就是問題所在。
對于一些短小的對象行楞,復制成本遠小于在堆上分配和回收操作攒暇。
Go Proverbs: A little copying is better than a little dependency.