SoFunction
Updated on 2025-03-05

Comparative analysis of the implementation method of go memory queue list vs slice

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 &amp;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!