這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。在C/C++裡,自己動手實現記憶體 Clerk是很常見的事情,寫過幾年C/C++程式的人可能都做過這樣的事情。這其中很重要的一個原因是C/C++不支援記憶體回收。但是既然go語言已經支援記憶體回收,還有必要自己去寫一個記憶體 Clerk嗎?我們做一個簡單的測試看看結果怎麼樣。測試平台:OS: ubuntu 12.04 x86_64CPU: i5 2.27GMEMORY: 8G
// ben1.go 自己實現記憶體 Clerkpackage main
type Pool struct {
buf []byte
}
func (p *Pool) alloc(size int) []byte{
if len(p.buf) < size{
l := 1024 * 1024
for l < size{
l += l
if l <= 0 {
panic("out of memory")
}
}
p.buf = make([]byte, l)
}buff := p.buf[:size]p.buf = p.buf[size:]return buff
}
func main() {
var p Poolfor i := 0; i < 10000000;i++ {
_ = p.alloc(100)
}
}
// ben2.go 系統記憶體 Clerkpackage main
func main() {
for i := 0; i < 10000000;i++ {
_ = make([]byte, 100)
}
}
編譯測試:go build ben1.gotime ./ben1go build ben2.gotime ./ben2
測試結果:
次數 |
ben1(s) |
ben2(s) |
1 |
0.308 |
2.057 |
2 |
0.304 |
2.048 |
3 |
0.308 |
2.093 |
平均 |
0.307 |
2.066 |
結論:可以看到,自己實現的記憶體 Clerk的執行時間大約是系統記憶體 Clerk的十分之一,差不多是一個數量級的差距。因此對於一些特定應用情境,比如網路程式庫等,使用自訂記憶體 Clerk還是很有必要的。由於go語言提供了垃圾收集功能,所以實現自訂記憶體 Clerk相比較在C/C++裡簡單很多。但是對於自訂記憶體 Clerk,還需要注意多goroutine下的同步問題。