使用指针来传递通道

huangapple go评论64阅读模式
英文:

Using pointer to channel

问题

使用指向通道的指针是否是一个好的实践?例如,我并发地读取数据,并使用通道传递这些数据map[string]string,然后在getSameValues()函数中处理这个通道。

func getSameValues(results *chan map[string]string) []string {
    var datas = make([]map[string]string, len(*results))
    i := 0
    for values := range *results {
        datas[i] = values
        i++
    }
}

我这样做的原因是因为chan map[string]string中将会有数百万个数据,并且可能会有多个映射。因此,我认为如果我可以传递指向函数的指针,这将是一个不错的方法,这样就不会复制数据,以节省一些内存资源。

Effective Go中,我没有找到一个好的实践方法。所以我对我的方法有些怀疑。

英文:

Is it good practice to use pointer to channel? For example I read the data concurrently and pass those data map[string]sting using channel and process this channel inside getSameValues().

func getSameValues(results *chan map[string]string) []string {
	var datas = make([]map[string]string, len(*results))
    i := 0
	for values := range *results {
		datas[i] = values
		i++
	}
}

The reason I do this is because the chan map[string]string there will be around millions of data inside the map and it will be more than one map.

So I think it would be a good approach if I can pass pointer to the function so that it will not copy the data to save some resource of memory.

I didn't find a good practice in effective go. So I'm kinda doubt about my approach here.

答案1

得分: 48

使用指向通道、映射、函数、接口或切片的指针来提高效率是不好的实践。

这些类型的值具有固定的小尺寸,与值的长度或容量无关。内部指针引用变量大小的数据。

通道、映射和函数的大小与指针相同。因此,复制这些类型的值的运行时成本与复制指向该值的指针的成本相同。

接口的大小是指针的两倍,切片的大小是指针的三倍。复制这些类型的值的成本高于复制指针的成本。这种额外的复制成本通常低于或等于解引用指针的成本。

英文:

It is poor practice to use pointers to channels, maps, functions, interfaces, or slices for efficiency.

Values of these types have a small fixed size independent of the length or capacity of the value. An internal pointer references the variable size data.

Channels, maps, and functions are the same size as a pointer. Therefore, the runtime cost of copying a value of these types is identical to copying a pointer to the value.

Interfaces are two × the size of a pointer, and slices are three × the size of a pointer. The cost of copying a value of these types is higher than copying a pointer. That extra copying cost is often lower or equal to the cost of dereferencing the pointer.

答案2

得分: 23

在Go语言中,有六种值的类别是通过引用而不是值传递的。它们是指针(pointers)、切片(slices)、映射(maps)、通道(channels)、接口(interfaces)和函数(functions)。

从CPU实际执行的操作来看,复制引用值和复制指针应该被认为是相等的(至少作为一个很好的近似)。

因此,几乎从不有用地使用指向通道的指针,就像很少有用地使用指向映射的指针一样。

因为你的通道携带的是映射,通道是引用类型,映射也是引用类型,所以CPU所做的只是在堆上复制指针。在通道的情况下,它还会进行goroutine同步。

如果想进一步阅读,请打开Effective Go并在页面中搜索单词"reference"。

英文:

In Go, there are six categories of value that are passed by reference rather than by value. These are pointers, slices, maps, channels, interfaces and functions.

Copying a reference value and copying a pointer should be considered equal in terms of what the CPU has to actually do (at least as a good approximation).

So it is almost never useful to use pointers to channels, just like it is rarely useful to use pointers to maps.

Because your channel carries maps, the channel is a reference type and so are the maps, so all the CPU is doing is copying pointers around the heap. In the case of the channel, it also does goroutine synchronisation too.

For further reading, open Effective Go and search the page for the word 'reference'.

答案3

得分: 14

在Golang中,所有的东西都是按值传递的。即使指针也是一种类型,并且被赋予内存地址的值。所以它们也是值。

(扩展Rick的回答)实际上有六种类型保存指针值,而对这些类型的指针(即指向指针的指针)并没有帮助:

  1. 指针
  2. 切片
  3. 映射
  4. 通道
  5. 接口
  6. 函数
英文:

Everything in Golang is passed by value. Even pointers are a type and assigned the value of the memory address. So they are values too.

(Extending Rick's answer) There are actually six types that hold pointer values and a pointer to these (i.e. a pointer to a pointer) types doesn't help anyway:

  1. pointers
  2. slices
  3. maps
  4. channels
  5. interfaces
  6. function

huangapple
  • 本文由 发表于 2017年6月4日 13:50:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/44351159.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定