什么时候返回值什么时候返回指针?

2020-04-08 11:15:55 +08:00
 index90
自从了解到“逃逸机制”,写程序时心智负担增加不少。
平时开发时,是否需要有意识地去考虑内存分配问题?
还是更专注于语义?有没有这方面的方法论?
4307 次点击
所在节点    Go 编程语言
24 条回复
no1xsyzy
2020-04-08 11:30:18 +08:00
这方面的方法论比 go 语言还老得多:
premature optimization is the root of all evil
behanga
2020-04-08 11:57:20 +08:00
如果是 C++,就用只能指针啊,不怕泄露,随便用。
behanga
2020-04-08 11:57:40 +08:00
只能->智能
fluorinedog
2020-04-08 12:07:51 +08:00
gc 语言考虑啥 allocation 问题... 瞎写就是了,先把功能写完,然后再 profiling 优化...
根据我的经验,真正的热点往往不是你想象的那些,所以提前优化确实是万恶之源。
kkeiko
2020-04-08 12:34:49 +08:00
先说什么语言,不同语言虽然语法上看起来都叫指针,但底层原理其实都不太一样,你既然想要在合适的地方使用指针来提高性能,那就要了解所使用语言的底层原理是怎么实现指针的。
kaedea
2020-04-08 13:16:44 +08:00
逃逸机制能细讲一下?
cmdOptionKana
2020-04-08 13:17:34 +08:00
逃逸机制是指什么?
index90
2020-04-08 13:21:41 +08:00
@kaedea
@cmdOptionKana
Google Golang Escape Analysis
yongestcat
2020-04-08 13:43:17 +08:00
逃逸机制是啥 求科普
hst001
2020-04-08 13:45:38 +08:00
如果程序不是那种需要注重性能,不要考虑这些。真的需要性能的程序,用什么语言写都一样会增加心智负担。

简单的说,大对象使用指针,小对象,比如只有几个 int 类型字段,可以使用值拷贝,没有明确的分界线可以区分怎么使用,因为还要考虑到实际对象产生的数量,这点只有实际 profiling 才知道。

另外 map 类型的 key/value 也是有讲究的,会影响到 gc 。

不过还是那一句,撸代码的时候不如把时间花在逻辑设计上面,别瞎优化(万一不小心负优化了呢?),跑完再优化。
pwli
2020-04-08 13:46:40 +08:00
没必要过早优化吧
pwli
2020-04-08 13:48:47 +08:00
@yongestcat 本来应该是在栈上分配的,一看外部还保留着引用,这种就会逃逸到堆上,这只是一种简单的场景
useben
2020-04-08 14:04:50 +08:00
逃逸机制没必要在开发阶段考虑吧, 而且大多数情况也影响不到你的业务吧, 后面有影响直接 pprof 优化就是了
ppphp
2020-04-08 14:28:08 +08:00
写 go 性能早就不在意了,传指针还是值只看用的函数是不是只读这个对象的,是只读的就传值,有修改就传指针
zhangchioulin
2020-04-08 14:53:39 +08:00
这方便的讨论很多,列举一个我觉得很棒的:
https://stackoverflow.com/questions/23542989/pointers-vs-values-in-parameters-and-return-values

1. Slices, maps, channels, strings, function values, and interface values 内部用指针实现,返回指向它们的指针通常是多余的。
2. 大型结构体或需要更改返回值情况用指针,否则返回值
2.1 大型结构体?当你把结构体的 field 拆分开来放到方法中时你觉得参数很多时,那就是“大型结构体”
Jirajine
2020-04-08 15:06:35 +08:00
反正有 GC,你完全没必要去区分堆栈。

https://golang.org/doc/faq#stack_or_heap

>How do I know whether a variable is allocated on the heap or the stack? 
From a correctness standpoint, you don't need to know. Each variable in Go exists as long as there are references to it. The storage location chosen by the implementation is irrelevant to the semantics of the language.

是否传指针也没必要想太多,基本类型和本身就是引用的传值,其他一律传指针。
timothyye
2020-04-08 15:08:04 +08:00
感觉 Rust 的 ownership 机制能规避这些问题
scnace
2020-04-08 16:11:53 +08:00
前天看了 Go 夜读的内存对齐,也发现之前写的代码或多或少会有点问题(有很多的多余的内存分配),但是我一直觉得这些属于 suggestions 和,真正在这种地方遇到瓶颈的地方的场景很少,至少在平常的业务场景中,把某段业务逻辑设计再精简点,少几次 I/O 操作,优化下算法复杂度,往往产出比花在这些地方要值得。不过,很多常见优化项可以通过配置 IDE/Editor 的 golang ci lint 规则解决就是了
lewinlan
2020-04-08 16:39:02 +08:00
go 故意没有在文档中说堆栈的区别,就是让我们不要去关心堆栈问题。
同意前排的观点,先实现功能,后期再 profile 优化,别想太多。
Cloutain
2020-04-08 17:28:41 +08:00
你看看,我们用易语言的人完全不用担心什么 GC 逃逸机制,指针传递就万事大吉了ε=ε=ε=┏(゜ロ゜;)┛逃

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/660360

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX