go 的内存优势在部分场景比想象中多

85 天前
 momowei

不是吵架帖子,但经常看 go 和 java 比较的时候,经常有人说,go 节省点的内存跟程序员相比根本不值得一提,我越想越觉得不对劲,对于最常规的 crud 来说,不得不说 java 确实比 go 还是要一些的,不过事实是 java 或者 php 程序员转 go 其实狠快根本没那么难,而且现在环境下程序员不一定就很贵了。

go 和 java 我自己都在写,一般来说对于不差钱的国企和政府以及企业市场,java 确实是最适合的,但是我也自己做一些小产品和项目给一些小公司,我能感觉到 java 和 go 对你拿单的成本影响是很大的,比如我有一个订票(城际定制商务车业务)小程序,有时候是我自己提供云服务器,我不得不说物理机的内存确实狠便宜,可是云服务器的内存真的很贵,新用户还不明显,老用户续费狠明显,在一台 2 核 4g 的云服务器上,我一般自建数据库和 redis,然后再配合 go 的应用,因为可能面对好几个客户,会有一些自定义需求,所以部署个五六个是狠轻松的,因为每个应用的访问量并不大,但如果是 java 是很难这样子搞得,这样给了自己很大得利润空间以及拿单成本。

说了这么多,我只能说 go 其实更适合个人开发者和成本敏感型得小团队,因为一般这样团队,都自己写程序,最大得成本就是云服务得开支了,最后再说一句云服务器得内存,cpu,宽带真得很贵,动不动类似 spring 全家桶那样得架构真得狠费机器。

14517 次点击
所在节点    Go 编程语言
148 条回复
zhouhu
84 天前
主要是 spring boot ,还有就是 java object header 占用。
前者市面上应该有很多代替品
后者的话,JEP 450: Compact Object Headers (Experimental) 发布了会有重大改善
fox0001
84 天前
golang ,对我来说,一直只是玩玩,直到被 grpc 震惊……
kalayygl001
84 天前
给某师上了台 Intel 8380h*2/512G / 960ssd *2 和 intel 4310*2/256G/4TB*4 , 跑的 java 服务崩了
居然说服务器和系统问题,
这 java………………
james122333
84 天前
@zhjunjun

我 就算你不写 框架也会写
两条路 第一反射 第二代码生成
代码生成比较麻烦 代码量也变多了
james122333
84 天前
回到正题不管什么语言全自写才是最省内存和 cpu 资源的
Charlie17Li
84 天前
既然 golang 这么好,有没有推荐的 golang web 开发实践之类的呢,java 转 golang web ,写后端处理 err 有点难受,以及参数检验也好原始
jeesk
84 天前
@zhjunjun 你不用, 不代表别人不用。
jeesk
84 天前
随便说一个场景,golang 里面要上传超大文件, 文件达到 几个 g ,如果网络传输超快, 这是时候如果你再写入一个新文件,耗时增加一倍, 如果将临时文件 rename , 上传时间减少一半,对于有性能有 kpi 的项目, 标准库里面没有暴露临时文件字段,这个时候反射就很有作用了。 当然你也可以自己上传的解析。
lesismal
83 天前
@fox0001 grpc 有啥可震惊的... 主要就是靠着谷歌爹的光环, 另外就是郭德纲那句: 同行(thrift 那些垃圾)衬托

grpc 除了跨语言优势, 性能不值一提:
https://colobu.com/2022/07/31/2022-rpc-frameworks-benchmarks/
james122333
83 天前
@lesismal

我用标准 rpc 确实不错 应该算是标准库偏少数拿的出手的 不过还是因为我不想用复杂的东西
lemayi
83 天前
@newaccount 不会还觉得写 go 多复杂吧
bv
83 天前
@jeesk #108 这倒是个不错的思路,我看了下,用不到反射,只需要简单的断言就可以了。

func saveFile(upload *multipart.FileHeader, dst string) error {
srcFile, err := upload.Open()
if err != nil {
return err
}
defer srcFile.Close()

if file, ok := srcFile.(*os.File); ok {
return os.Rename(file.Name(), dst)
}

dstFile, err := os.Create(dst)
if err != nil {
return err
}
defer dstFile.Close()

_, err = io.Copy(dstFile, srcFile)

return err
}
jeesk
83 天前
@bv 这样不好, 2 次复制了. 最好一次第一次直接解析临时文件, 然后 rename, copy 对于磁盘的性能占用很大,特别上 g 的大文件.
guanzhangzhang
83 天前
@jeesk #113 🤔file.seek 也可以吧,直接 seek 写,全部接收完了 rename
bv
83 天前
@jeesk #113 注意看:如果断言是 *os.FIle 就 os.Rename() 。不是才走 io.Copy 。
jeesk
83 天前
@bv
@guanzhangzhang

看到了, 断言好像是必要的。

最开始我记得也是自己 rename, 发现不太行, 才用的反射。
jeesk
83 天前
@bv 这里直接使用 rename 是不行的。 我自己手动设置了临时的缓存目录一样不行。 后面拿到真是的文件对象才能 rename 。
bv
83 天前
@jeesk #117 不明白你为何不行,至少我这边自测是成功的。
同时也测试出了 rename 存在一个限制:在 Linux 中,不同分区/分区格式不同时,会报错:rename <src> <dest>: invalid cross-device link ,这并不是上面的代码使用方式不对,只是系统低层的限制。rename 出错最好不要直接返回错误,而是要退化到 io.Copy 去兜底。
jeesk
83 天前
@bv cross-device link 错误后,直接拿到文件去 rename 即可.
zhjunjun
83 天前
go 里面尽量少用反射,本身和 java 的机制也不一样,没必要拿 java 那套来写 go ,这样本末倒置。

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

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

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

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

© 2021 V2EX