go內(nèi)存隊列l(wèi)ist VS slice實現(xiàn)方式對比分析
go隊列的實現(xiàn)方式
golang中沒有隊列這種數(shù)據(jù)結(jié)構(gòu),通常需要自己實現(xiàn),常見的可以通過list或slice實現(xiàn)。
list是"container/list"中的數(shù)據(jù)結(jié)構(gòu),用雙向鏈表實現(xiàn),可以用來做隊列:
//入隊
func (l *List) PushBack(v interface{}) *Element
//出隊:先Front()取得頭,然后Remove()刪除
func (l *List) Front() *Element
func (l *List) Remove(e *Element) interface{}slice實現(xiàn)隊列的方式:
var s []obj s = append(s, obj) //入隊 s = s[1:] //出隊
benchmark測試比較
benchmark測試代碼: 隊列中存入object對象
type EventMsg struct {
Id string
Msg string
}
func BenchmarkQueue_ListObject(b *testing.B) {
var l = list.New()
for i := 0; i < b.N; i++ {
l.PushBack(EventMsg{
Id: strconv.Itoa(i),
Msg: "1:abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz",
})
l.PushBack(EventMsg{
Id: strconv.Itoa(i),
Msg: "1:opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn",
})
l.Remove(l.Front())
}
}
func BenchmarkQueue_SliceObject(b *testing.B) {
var q []EventMsg
for i := 0; i < b.N; i++ {
q = append(q, EventMsg{
Id: strconv.Itoa(i),
Msg: "1:abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz",
})
q = append(q, EventMsg{
Id: strconv.Itoa(i),
Msg: "1:opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn",
})
q = q[1:]
}
}benchmark測試代碼:隊列中存入Object指針對象
func BenchmarkQueue_ListObjPtr(b *testing.B) {
var l = list.New()
for i := 0; i < b.N; i++ {
l.PushBack(&EventMsg{
Id: strconv.Itoa(i),
Msg: "1:abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz",
})
l.PushBack(&EventMsg{
Id: strconv.Itoa(i),
Msg: "1:opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn",
})
l.Remove(l.Front())
}
}
func BenchmarkQueue_SliceObjPtr(b *testing.B) {
var q []*EventMsg
for i := 0; i < b.N; i++ {
q = append(q, &EventMsg{
Id: strconv.Itoa(i),
Msg: "1:abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz",
})
q = append(q, &EventMsg{
Id: strconv.Itoa(i),
Msg: "1:opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn",
})
q = q[1:]
}
}benchmark測試結(jié)果
# go test -bench=BenchmarkQueue -count=1 -benchmem -cpu 4
BenchmarkQueue_ListObject-4 1000000 1423 ns/op 175 B/op 5 allocs/op
BenchmarkQueue_ListObjPtr-4 1000000 1124 ns/op 175 B/op 5 allocs/op
BenchmarkQueue_SliceObject-4 1000000 1574 ns/op 357 B/op 1 allocs/op
BenchmarkQueue_SliceObjPtr-4 1831449 662.7 ns/op 161 B/op 3 allocs/op
PASS
ok github.com/go_list/bench_test 6.144s
結(jié)論:
- 不管用list還是slice,隊列中存儲對象指針的性能,要好于直接存儲對象;
- slice實現(xiàn)的隊列,存儲指針對象時性能最好;
- list實現(xiàn)的隊列,不管是存儲對象還是指針對象,其性能差異不是太大;
Open-falcon的隊列實現(xiàn)
open-falcon使用list和mutex實現(xiàn)了一個協(xié)程安全的內(nèi)存隊列。
實現(xiàn)代碼:https://github.com/toolkits/c...
type SafeList struct {
sync.RWMutex
L *list.List
}
func NewSafeList() *SafeList {
return &SafeList{L: list.New()}
}
//入隊
func (this *SafeList) PushFront(v interface{}) *list.Element {
this.Lock()
e := this.L.PushFront(v)
this.Unlock()
return e
}
//出隊
func (this *SafeList) PopBack() interface{} {
this.Lock()
if elem := this.L.Back(); elem != nil {
item := this.L.Remove(elem)
this.Unlock()
return item
}
this.Unlock()
return nil
}參考:http://m.fzitv.net/jiaoben/2957122cc.htm
以上就是go內(nèi)存隊列l(wèi)ist VS slice實現(xiàn)方式對比分析的詳細內(nèi)容,更多關(guān)于go內(nèi)存隊列l(wèi)ist slice的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go語言基于HTTP的內(nèi)存緩存服務(wù)的實現(xiàn)
這篇文章主要介紹了Go語言基于HTTP的內(nèi)存緩存服務(wù),本程序采用REST接口,支持設(shè)置(Set)、獲取(Get)和刪除(Del)這3個基本操作,同時還支持對緩存服務(wù)狀態(tài)進行查詢,需要的朋友可以參考下2022-08-08
詳解golang避免循環(huán)import問題(“import cycle not allowed”)
這篇文章主要給大家介紹了關(guān)于golang中不允許循環(huán)import問題("import cycle not allowed")的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
Go項目在GoLand中導(dǎo)入依賴標(biāo)紅問題的解決方案
這篇文章主要介紹了Go項目在GoLand中導(dǎo)入依賴標(biāo)紅問題的解決方案,文中通過代碼示例講解的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-06-06
Golang在Window環(huán)境使用Imagick7的過程
這篇文章主要介紹了Golang在Window環(huán)境使用Imagick7的過程,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11

