哪种通道类型在 Go 中使用最少的内存?
Which channel type uses the least amount of memory in Go?
我发现自己经常使用频道让事情停下来。在这些情况下,通道仅用作信号传输方式,实际使用了 none 的数据。
例如:
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
Run/view it如果你在 golang 操场上请。
我的问题是:
Go 中哪种通道类型的内存占用最少?
例如bool chan 是否需要比空 struct{} chan 更少的开销?
chan bool
chan byte
chan interface{}
chan struct{}
...
还有别的吗?
查看频道的latest implementation,这不是一个简单的结构:
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
}
服务员队列的元素也是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
}
你看,很多字节。即使为空频道创建任何元素,这也可以忽略不计。
但是,我希望所有空通道都采用相同数量的 space,无论基础类型如何,因此如果您打算只关闭通道,则不会有任何区别(实际元素似乎由指针持有)。一个快速测试支持它:
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)
}
我看不出 chan struct{}
和 chan [64000]byte
之间有什么区别,两者都会在我的 64 位机器上占用约 1GB 的空间,这让我相信在某处创建单个通道的开销100 个字节。
总之,这并不重要。我个人会使用 struct{}
,因为它是唯一真正的空类型(实际上大小为 0),清楚地表明无意发送任何有效负载。
我发现自己经常使用频道让事情停下来。在这些情况下,通道仅用作信号传输方式,实际使用了 none 的数据。
例如:
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
Run/view it如果你在 golang 操场上请。
我的问题是:
Go 中哪种通道类型的内存占用最少?
例如bool chan 是否需要比空 struct{} chan 更少的开销?
chan bool
chan byte
chan interface{}
chan struct{}
...
还有别的吗?
查看频道的latest implementation,这不是一个简单的结构:
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
}
服务员队列的元素也是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
}
你看,很多字节。即使为空频道创建任何元素,这也可以忽略不计。
但是,我希望所有空通道都采用相同数量的 space,无论基础类型如何,因此如果您打算只关闭通道,则不会有任何区别(实际元素似乎由指针持有)。一个快速测试支持它:
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)
}
我看不出 chan struct{}
和 chan [64000]byte
之间有什么区别,两者都会在我的 64 位机器上占用约 1GB 的空间,这让我相信在某处创建单个通道的开销100 个字节。
总之,这并不重要。我个人会使用 struct{}
,因为它是唯一真正的空类型(实际上大小为 0),清楚地表明无意发送任何有效负载。