How to implement go queues
There is no data structure like a queue in golang, which usually needs to be implemented by itself. Common ones can be implemented through list or slice.
List is a data structure in "container/list", implemented using a two-way linked list, which can be used as a queue:
//Enter the teamfunc (l *List) PushBack(v interface{}) *Element //Departure: First Front() gets the header, then Remove() deletes itfunc (l *List) Front() *Element func (l *List) Remove(e *Element) interface{}
How to implement the queue in slice:
var s []obj s = append(s, obj) //Enter the teams = s[1:] //Departure
benchmark test comparison
benchmark test code: save object object in queue
type EventMsg struct { Id string Msg string } func BenchmarkQueue_ListObject(b *) { var l = () for i := 0; i < ; i++ { (EventMsg{ Id: (i), Msg: "1:abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz", }) (EventMsg{ Id: (i), Msg: "1:opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn", }) (()) } } func BenchmarkQueue_SliceObject(b *) { var q []EventMsg for i := 0; i < ; i++ { q = append(q, EventMsg{ Id: (i), Msg: "1:abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz", }) q = append(q, EventMsg{ Id: (i), Msg: "1:opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn", }) q = q[1:] } }
benchmark test code: Save Object in the queuePointing to the image
func BenchmarkQueue_ListObjPtr(b *) { var l = () for i := 0; i < ; i++ { (&EventMsg{ Id: (i), Msg: "1:abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz", }) (&EventMsg{ Id: (i), Msg: "1:opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn", }) (()) } } func BenchmarkQueue_SliceObjPtr(b *) { var q []*EventMsg for i := 0; i < ; i++ { q = append(q, &EventMsg{ Id: (i), Msg: "1:abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz", }) q = append(q, &EventMsg{ Id: (i), Msg: "1:opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn-opqrstuvwxyzabcdefghijklmn", }) q = q[1:] } }
benchmark test results
# 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 /go_list/bench_test 6.144s
in conclusion:
- Whether using list or slice, the performance of storing object pointers in the queue is better than storing objects directly;
- The queue implemented by slice has the best performance when the storage pointer is targeted;
- The performance difference between the queue implemented by list, whether it is a storage object or a target object;
Open-falcon queue implementation
open-falcon uses list and mutex to implement a coroutine-safe memory queue.
Implementation code:/toolkits/c...
type SafeList struct { L * } func NewSafeList() *SafeList { return &SafeList{L: ()} } //Enter the teamfunc (this *SafeList) PushFront(v interface{}) * { () e := (v) () return e } //Get out of the teamfunc (this *SafeList) PopBack() interface{} { () if elem := (); elem != nil { item := (elem) () return item } () return nil }
refer to:https:///jiaoben/
The above is the detailed content of the comparison and analysis of the implementation method of go memory queue list vs slice. For more information about go memory queue list slice, please pay attention to my other related articles!