What type of channel uses the least amount of memory in Go?

I often use channels to make things stop. In these cases, the channel is used solely as a means of signaling, and none of the data is actually used.

For instance:

package main import ( "fmt" "time" ) func routine(stopChan chan bool) { fmt.Println("goroutine: I've started!") <-stopChan fmt.Println("goroutine: Cya'round pal") } func main() { fmt.Println("main: Sample program run started") stopChan := make(chan bool) go routine(stopChan) fmt.Println("main: Fired up the goroutine") stopChan <- true time.Sleep(1 * time.Second) fmt.Println("main: Sample program run finished") } 

 // Sample output: // // main: Sample program run started // main: Fired up the goroutine // goroutine: I've started! // goroutine: Cya'round pal // main: Sample program run finished 

Launch / view it , if you like, on the golang playground.


My question is:

What type of channel has the lightest amount of memory in Go?

eg. Will a bool chan require less overhead than an empty {} chan?

chan bool

chan byte

chan interface{}

chan struct{}

...

something else?

+6
source share
1 answer

Considering the latest version of the channel, this is not a trivial structure:

 type hchan struct { qcount uint // total data in the queue dataqsiz uint // size of the circular queue buf unsafe.Pointer // points to an array of dataqsiz elements elemsize uint16 closed uint32 elemtype *_type // element type sendx uint // send index recvx uint // receive index recvq waitq // list of recv waiters sendq waitq // list of send waiters lock mutex } 

Waiter line items are also quite heavy :

 type sudog struct { g *g selectdone *uint32 next *sudog prev *sudog elem unsafe.Pointer // data element releasetime int64 nrelease int32 // -1 for acquire waitlink *sudog // g.waiting list } 

You see, a lot of bytes. Even if an element were created for an empty channel, this would be negligible.

However, I expect all empty channels to occupy the same space regardless of the base type, so if you only intend to close the channel, there will be no difference (the actual element seems to be held by the pointer). A quick test supports it:

 package main import ( "fmt" "time" ) func main() { // channel type type xchan chan [64000]byte a := make([]xchan, 10000000) // 10 million for n := range a { a[n] = make(xchan) } fmt.Println("done") time.Sleep(time.Minute) } 

I do not see the difference between chan struct{} and chan [64000]byte , and this leads to ~ 1 GB of use on my 64-bit machine, which makes me think that the overhead of creating one channel is approximately 100 bytes.

In conclusion, this is not a big deal. Personally, I would use struct{} , since it was the only really empty type (size 0 really), which clearly indicates the absence of intent on any sent payload.

+6
source

Source: https://habr.com/ru/post/988875/


All Articles