从C/C++过来,问几个关于go语言性能问题
我是才从C++迁移到go语言来的,因此对内存管理和变量生存期这块特别敏感,对效率也相对要求比较苛刻,开始使用过程中有很多困惑,可能还不习惯用GO吧,请高手指点:
1、有关channel的效率问题,比如我定义一个channel变量,ch1:=make(chan string) ,在goroutinue中向chan中读取(c<-ch1)和写入(ch1<-c)操作是否会产生string的复制代价,同理如果chan是一个很大的结构体,结构体里有大数组等,如果每次写入和读取chan都要复制一次数据,相当于c语言的memcpy,那么不仅会占用栈空间,而且造成程序效率底下。如果chan都定义为指针是否可以解决这个问题?是否会引入新的问题?
2、还是chan的问题,是否所有chan不用时都要执行关闭操作?如不关闭chan,垃圾回收是否会起作用?是否会造成内存泄露,资源是否一直占用?
假如有如下程序,在map中定义了插入了一个含有很多chan的结构体变量的元素,当删除这个元素时(没有显示关闭这些chan),是否会引发上述问题?
type MySTC struct {
ch1 chan [1000]int
ch2 chan string
ch3 chan []byte
a int
}
func main() {
m1 := make(map[int]MySTC)
m1[0] = MySTC{
ch1: make(chan [1000]int, 100),
ch2: make(chan string),
ch3: make(chan []byte),
a: 0,
}
fmt.Println(m1)
dosomething(m1)
delete(m1, 0)
for{
time.Sleep(time.second*100)
}
}
3、map的遍历问题,很欣慰的是go提供了range的变量操作,但是我想在遍历的时候为所有map中的数据加上一个'x',好像只能这样:
func test_map() {
m1 := make(map[int]string)
for i := 0; i < 5; i++ {
m1[i] = strconv.Itoa(i)
}
fmt.Println(m1)
for k, v := range m1 {
//v += "x" ,由于v是元素的copy,因此修改v不能更改相应的元素值
m1[k] += "x"
}
fmt.Println(m1)
}
感觉很不友好,既然我已经获取了m1[k]的值,可是我要修改它却要再一次调用m1[k],这不是又一次查询吗,很明显降低效率啊,我试了用&v报编译错误,这个问题在C++中可以把迭代器赋给一个引用变量来实现对容器元素的修改,可在Go语言中该怎么做呢?