从C/C++过来,问几个关于go语言性能问题

rwxdfbb 2014-12-12 09:51:36
我是才从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语言中该怎么做呢?
...全文
280 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
yumengwangluo 2021-06-23
  • 打赏
  • 举报
回复

+= "x" 这种情形在生产环境中应该很难遇到吧,一般value部分是一个结构体,用指针就没你的说的问题

你关心的性能问题,凭我个人的感觉大部分项目问题不大,以我的游戏服务器为例,5万机器人同时进行战斗,老机器志强e3-1230的cpu占用大约不到35%,真人登录上去玩起来也很流畅

根据官方的说法是性能可以达到c++的80%,我个人是不太信的,因为那些性能测试代码涉及的面相对偏窄且高度优化,但个人认为50%以上应该是没问题的。工具链也提供了强大的性能检测工具,利用这些工具做起优化来还是比较容易的

rwxdfbb 2014-12-13
  • 打赏
  • 举报
回复
引用 1 楼 pathletboy 的回复:
3、可以不获取v,只获取k
	for k, _ := range m1 {
		 m1[k] += "x"
	}
当然m1[k]是会发生一次hash查找的。
的确多执行了一次查询,可能是go设计的时候没有对效率考虑的很细致。 在C++中可以这样:
m1::iterator it = m1.begin();
for(; it!= m1.end(); ++it)
{
      sring& str = it->second;  //此处就不需要再次调用m1[it->first],而是直接用一个引用变量或者直接it->second+="x"即可
      str += "x";
}
pathletboy 2014-12-13
  • 打赏
  • 举报
回复
1、string是一个对象,里面有一个指针指向字符串,复制的时候只复制了这个对象,实际的字符串并没有被复制,在C/C++中可以认为只复制了一个指针变量,而且s[0] = x在golang中是不允许的,反正不能改,所以字符串根本就不需要复制了。另外golang有copy on write机制,很多对象写时才会发生复制。 2、不需要关闭,只要引用计数为0,就会被回收,另外不是关闭了就会释放,因为关闭后还是可能被引用着。 3、可以不获取v,只获取k
	for k, _ := range m1 {
		m1[k] += "x"
	}
当然m1[k]是会发生一次hash查找的。
一、Go语言的由来      Go语言亦叫Golong语言,是由谷歌Goggle公司推出。Go语言的主要开发者有:肯.汤姆逊(Ken Thompson)、罗布.派克(Rob Pike)和罗伯特.格里泽默(Robert Griesemer)。这三个都是大神,稍介绍一下他们的贡献:     肯.汤姆逊(Ken Thompson):图灵奖得主,Uinx发明人,B语言作者(C语言前身),还做飞行员,后来被谷歌挖走。     罗布.派克(Rob Pike):Unix团队和Plan 9操作系统计划的成员,与Ken老爷子共事多年,并共创出广泛使用的UTF-8 字元编码。     罗伯特.格里泽默(Robert Griesemer):曾协助制作Java的HotSpot编译器,和Chrome浏览器的JavaScript引擎V8。     膜拜一下大神的容颜:Ken老爷子(左),Rob Pike(右)         二、开发Go语言的初衷     根据Go语言开发者自述,近10多年,从单机时代的C语言到现在互联网时代的Java,都没有令人满意的开发语言,而 C++往往给人的感觉是,花了100%的经历,却只有60%的开发效率,产出比太低,Java和C#的哲学又来源于C++。并且,随着硬件的不断升级,这些语言不能充分的利用硬件及CPU。因此,一门高效、简洁、开源的语言诞生了。 三、Go语言的特点    Go语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发速度和易维护性,有人形容Go语言:Go = C + Python , 说明Go语言既有C静态语言程序的运行速度,又能达到Python动态语言的快速开发。 Go语言有以下特性: 1.自动垃圾回收     C/C++最头疼的就是指针,一不小心就野指针了或者又越界了。在Go语言里再也不用担心,也不用考虑delete或者free,系统自动会回收。 2.函数可以返回多个值     这个很神奇,大多数语言只能返回一个值,Go语言可以返回多个值。这个功能使得开发者再不用绞尽脑汁的想到底怎么返回值的设计,也不用为了传值专门定义一个结构体。 3.并发编程     Go语言天然并发,只需要关键字“go”就可以让函数并发执行,使得并发编程变得更为简单,这也是Go语言最大的优势。 四、Go语言能做什么开发     Go语言是非常有潜力的语言,是因为它的应用场景是目前互联网非常热门的几个领域,比如区块链开发、大型游戏服务端开发、分布式/云计算开发。像Goggle、阿里、京东等互联网公司都开始用Go语言开发自己的产品。

2,190

社区成员

发帖
与我相关
我的任务
社区描述
go语言学习与交流版
社区管理员
  • go语言社区
  • Freeman Z
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧