對於一些初學者,自知道 go 裡面的 array 以 pass-by-value 方式傳遞後,就莫名地引起 「恐慌」。外加諸多文章未作說明,就建議用 slice 代替 array,企圖避免資料拷貝,提公升效能。實際上,此做法有待商榷。某些時候怕會適得其反,倒造成不必要的效能損失。
用個簡單的示例說明。
package main
import
( "fmt"
)const capacity = 1024
func array
() [capacity]int
return d
}func slice
() int
return d
}func main
()
**很簡單,兩個函式分別返回 「內容相同」 的 array 和 slice。為避免編譯器優化,特填充了全部資料,以模擬 「真實」 資料複製行為。接下來,看看效能測試對比。
package main
import
( "testing"
)func benchmarkarray
(b *testing.b)
}func benchmarkslice
(b *testing.b)
}
這結果怕是顛覆了最初認知。array 非但擁有更好的效能,還避免了堆記憶體分配,也就是說減輕了 gc 壓力。為什麼會這樣?
熟悉彙編的,怕是很容易看出來。函式 array 返回值的複製只需用 "cx + rep" 指令就可完成。
整個 array 函式完全在棧上完成,而 slice 函式則需執行 makeslice,繼而在堆上分配記憶體,這就是問題所在。
對於一些短小的物件,複製成本遠小於在堆上分配和**操作。
go proverbs: a little copying is better than a little dependency.
Go 效能優化技巧 8 10
儘管反射 reflect 存在效能問題,但依然被頻繁使用,以彌補靜態語言在動態行為上的不足。只是某些時候,我們須對此做些變通,以提公升效能。為便於閱讀,以下示例均做了最大程度精簡。如果是 reflect.type,可將其快取,避免重複操作耗時。但 value 顯然不行,因為它和具體物件繫結,內部儲存...
Go 效能優化技巧 7 10
介面的用途無需多言。但這並不意味著可在任何場合使用介面,要知道通過介面呼叫和普通呼叫存在很大差別。首先,相比靜態繫結,動態繫結效能要差很多 其次,執行期需額外開銷,比如介面會複製物件,哪怕僅是個指標,也會在堆上增加乙個需 gc 處理的目標。顯然,對於壓力很大的內部元件之間,用介面有些得不償失。對比介...
Oracle SQL 效能優化技巧
sun2004發表於 2008 12 25 11 28 眾所周知,資料庫設計的好壞直接關係到資料庫執行的效率。根據筆者的經驗,對於提公升資料庫效能來說,合理的資料庫設計,比公升級伺服器的硬體配置,還要來的有效。但是,筆者無論是在跟同事合作,又或者是在論壇上跟相關同行交流的時候,總是會發現有些人有一些...