< 返回版块

lithbitren 发表于 2024-04-06 08:10

Tags:性能,protobuf

一般和rust有关的性能对比都是当爽文看的,一开始可能没比过某某gc语言,只要找准方法最终还是可以可以比赢性能的(虽然实现上可能会稍显复杂)。

今天在公众号上看到这篇文章:Rust 解码 Protobuf 数据比 Go 慢五倍?记一次性能调优之旅

具体技术细节没上手过不是很懂,但看作者优化了很久很辛苦还上了unsafe,还是没有打赢go。


Ext Link: https://mp.weixin.qq.com/s/ktOGySi9HJ31G2-IOfxHZw

评论区

写评论
TinusgragLin 2024-04-09 14:46

今天重看这篇文章,结合这里的评论区,我越来越觉得文章中“A语言比B语言怎么怎么样”的说辞确实不妥,容易有争议,内容上:

  1. 文章前半部分在讨论内存申请重用/池化,优化的大头在于 VictoriaMetrics 本身是一个时序数据库,其 WriteRequest 的 clear() 方法是内部的,对其中时间戳列表的清空做了相应的优化,而 proto::Message::clear() 完全是一个通用的方法,实际上是将其中的时间戳列表换成了另一个新列表。

  2. 后半部分从 protobuf 的 string(和 Rust 的 String)要求是 valid utf-8 string,因此有 utf-8 检查开销开始,讨论将协议中相应字段的类型改成 bytes 的可能性。 从这里又引出使用 bytes::Bytes 的 zero-copy 优化,为了能够进行安全的 zero-copy,Bytes 使用了引用计数的内存管理方式,这点和 Bytes 默认的边界检查一起带来了不容忽视的开销,而虽然 bytes::Bytes 的设计就是为了能够进行安全的 zero-copy 解码,但 proto 为了它的设计能够尽量通用,使用了 Buf trait,也引入了一个转换开销。

我个人觉得前半部分与语言无关;后半部分虽然可以说 Go 的 tracing GC 与引用计数系统比起来,在较短的时间尺度上确实有优势,毕竟引用计数系统在引用的时候还要来个 fetch_add_check,而 tracing GC 在GC触发次数比较少的时候,开销可以很少,但我觉得也不是那种 2 > 1 的情况,Swift 选择引用计数系统应该不是没理由的,引入“A语言比B语言如何如何”的语言有些不妥。

总之,我理解“A语言比B语言如何如何”在文中的出现是因为表达上的便捷性,但考虑到现在的网络环境,我觉得我会更加小心这样的措辞。

除此之外,边界检查的问题,我的经验是,它通常不会是耗时的大头,这种代价比较小的安全性提升还是值得的,更何况编译器有时也能把它自动优化掉。至于一些库的通用化设计和两个库耦合带来的开销,只能说 VictoriaMetrics 团队自己写 protobuf codec 确实是有理由的。

全称量词 2024-04-09 01:11

难绷,我都认输了,我确实有病,你确实很正常啊,为什么还骂我,不理解,哈哈。

985爷经常自嘲为带专,我还以为你也是985啊,没想到观察你行为感觉真是带专啊,那没事了,不和你玩啰。

--
👇
全称量词是儿子: 很难想象“请正面分析问题,而不是人身攻击。”这句话居然从你口中说出,特别是你之前还说了“分析问题就分析问题,没有必要天天给这拉踩”,纯纯的一个逗比,你连专科生都不如,有什么资格在这指手画脚的,feicai

--
👇
全称量词: 请正面分析问题,而不是人身攻击。

谢谢你的建议,听了你的话,我马上去第三人民医院挂了个号,结果发现我确实有病,好了,我马上要去住院了。

现在全世界就你最正常了,你是地球上最后一个正常的人类,拯救地球的任务就交给你了,加油。

哦,对了,提醒你一下,简历要发给人家哦。https://rustcc.cn/article?id=1ee1ec91-b67a-469f-9a51-20b42ca2ee07

--
👇
AnkoGo123: 你有病吧?天天?你是不是有病?有病左转出门看医生去,容不得一点跟你反向的观点,你怎么不去当教育家??

--
👇
全称量词: 如果不是 Go 有 GC, 你还不写 Go 了呢。你这话还可以反着说,如果不是 rust 没 gc,go 赢过 rust 的几率几乎为 0。分析问题就分析问题,没有必要天天给这拉踩。

--
👇
AnkoGo123: 很正常,rust目前的标准库优化不如go,当然还有其他方面,如果不是go有gc,rust赢过go的几率几乎为0,也就是rust的性能一定会比cpp慢一点,无gc的go其实速度跟cpp应该是一样快的

zombie110year 2024-04-09 01:09

这也能吵架,而且还要改成“xxxx是儿子”这样的昵称,难以想象这是成年人做出的行为。

ankoGo 2024-04-09 00:41

很难想象“请正面分析问题,而不是人身攻击。”这句话居然从你口中说出,特别是你之前还说了“分析问题就分析问题,没有必要天天给这拉踩”,纯纯的一个逗比,你连专科生都不如,有什么资格在这指手画脚的,feicai

--
👇
全称量词: 请正面分析问题,而不是人身攻击。

谢谢你的建议,听了你的话,我马上去第三人民医院挂了个号,结果发现我确实有病,好了,我马上要去住院了。

现在全世界就你最正常了,你是地球上最后一个正常的人类,拯救地球的任务就交给你了,加油。

哦,对了,提醒你一下,简历要发给人家哦。https://rustcc.cn/article?id=1ee1ec91-b67a-469f-9a51-20b42ca2ee07

--
👇
AnkoGo123: 你有病吧?天天?你是不是有病?有病左转出门看医生去,容不得一点跟你反向的观点,你怎么不去当教育家??

--
👇
全称量词: 如果不是 Go 有 GC, 你还不写 Go 了呢。你这话还可以反着说,如果不是 rust 没 gc,go 赢过 rust 的几率几乎为 0。分析问题就分析问题,没有必要天天给这拉踩。

--
👇
AnkoGo123: 很正常,rust目前的标准库优化不如go,当然还有其他方面,如果不是go有gc,rust赢过go的几率几乎为0,也就是rust的性能一定会比cpp慢一点,无gc的go其实速度跟cpp应该是一样快的

全称量词 2024-04-08 20:17

请正面分析问题,而不是人身攻击。

谢谢你的建议,听了你的话,我马上去第三人民医院挂了个号,结果发现我确实有病,好了,我马上要去住院了。

现在全世界就你最正常了,你是地球上最后一个正常的人类,拯救地球的任务就交给你了,加油。

哦,对了,提醒你一下,简历要发给人家哦。https://rustcc.cn/article?id=1ee1ec91-b67a-469f-9a51-20b42ca2ee07

--
👇
AnkoGo123: 你有病吧?天天?你是不是有病?有病左转出门看医生去,容不得一点跟你反向的观点,你怎么不去当教育家??

--
👇
全称量词: 如果不是 Go 有 GC, 你还不写 Go 了呢。你这话还可以反着说,如果不是 rust 没 gc,go 赢过 rust 的几率几乎为 0。分析问题就分析问题,没有必要天天给这拉踩。

--
👇
AnkoGo123: 很正常,rust目前的标准库优化不如go,当然还有其他方面,如果不是go有gc,rust赢过go的几率几乎为0,也就是rust的性能一定会比cpp慢一点,无gc的go其实速度跟cpp应该是一样快的

ankoGo 2024-04-08 18:47

你有病吧?天天?你是不是有病?有病左转出门看医生去,容不得一点跟你反向的观点,你怎么不去当教育家??

--
👇
全称量词: 如果不是 Go 有 GC, 你还不写 Go 了呢。你这话还可以反着说,如果不是 rust 没 gc,go 赢过 rust 的几率几乎为 0。分析问题就分析问题,没有必要天天给这拉踩。

--
👇
AnkoGo123: 很正常,rust目前的标准库优化不如go,当然还有其他方面,如果不是go有gc,rust赢过go的几率几乎为0,也就是rust的性能一定会比cpp慢一点,无gc的go其实速度跟cpp应该是一样快的

ankoGo 2024-04-08 18:44

非也,那是你的观点,我不认为这只是第三方库的锅

--
👇
JackySu: 纯第三方库自己优化问题这都能和gc扯上 无语

👇
AnkoGo123: 很正常,rust目前的标准库优化不如go,当然还有其他方面,如果不是go有gc,rust赢过go的几率几乎为0,也就是rust的性能一定会比cpp慢一点,无gc的go其实速度跟cpp应该是一样快的

ankoGo 2024-04-08 18:44

你确实说对了,我也同意,同理,如果rust中存在更好的更快的序列化与反序列化的库,那肯定作者也提出来了,我相信这个不只是第三方库的原因,因为人家go能做到,你rust的第三方库做不到或者难做到,归根结底最终还是语言问题,而不是简单第三方库的锅

--
👇
lithbitren: 水平不到家没办法,序列化/反序列化向来都是很trick的东西,放别的的语言,也没多少人能做好。我也没能部署文章中的测试环境,确实提不出什么有效建议,只能说是学习了。

特别是里面提到的字符串共享的问题,我这种纯纯低手就是String::clone一把梭,没啥思维负担,但性能就那样,也想过用Arc或者Bytes,但最终还是没有付诸实践,文中确实也提到了这方面的开销。至于像文中搞unsafe切片的纯属艺高人胆大了,我是万万不敢想的。

--
👇
AnkoGo123: 从楼主的口吻来看,似乎很质疑人家,但是自己又提不出任何更有效的方案!

ankoGo 2024-04-08 18:39

你是一个恶心的nt rust粉

--
👇
Bai-Jinlin: 要是这个论坛有屏蔽功能,我第一个就把下面那个哥们屏蔽了

--
👇
JackySu: 纯第三方库自己优化问题这都能和gc扯上 无语

👇
AnkoGo123: 很正常,rust目前的标准库优化不如go,当然还有其他方面,如果不是go有gc,rust赢过go的几率几乎为0,也就是rust的性能一定会比cpp慢一点,无gc的go其实速度跟cpp应该是一样快的

Bai-Jinlin 2024-04-08 09:29

要是这个论坛有屏蔽功能,我第一个就把下面那个哥们屏蔽了

--
👇
JackySu: 纯第三方库自己优化问题这都能和gc扯上 无语

👇
AnkoGo123: 很正常,rust目前的标准库优化不如go,当然还有其他方面,如果不是go有gc,rust赢过go的几率几乎为0,也就是rust的性能一定会比cpp慢一点,无gc的go其实速度跟cpp应该是一样快的

JackySu 2024-04-08 02:47

纯第三方库自己优化问题这都能和gc扯上 无语

👇
AnkoGo123: 很正常,rust目前的标准库优化不如go,当然还有其他方面,如果不是go有gc,rust赢过go的几率几乎为0,也就是rust的性能一定会比cpp慢一点,无gc的go其实速度跟cpp应该是一样快的

作者 lithbitren 2024-04-07 17:10

水平不到家没办法,序列化/反序列化向来都是很trick的东西,放别的的语言,也没多少人能做好。我也没能部署文章中的测试环境,确实提不出什么有效建议,只能说是学习了。

特别是里面提到的字符串共享的问题,我这种纯纯低手就是String::clone一把梭,没啥思维负担,但性能就那样,也想过用Arc或者Bytes,但最终还是没有付诸实践,文中确实也提到了这方面的开销。至于像文中搞unsafe切片的纯属艺高人胆大了,我是万万不敢想的。

--
👇
AnkoGo123: 从楼主的口吻来看,似乎很质疑人家,但是自己又提不出任何更有效的方案!

全称量词 2024-04-07 15:44

如果不是 Go 有 GC, 你还不写 Go 了呢。你这话还可以反着说,如果不是 rust 没 gc,go 赢过 rust 的几率几乎为 0。分析问题就分析问题,没有必要天天给这拉踩。

--
👇
AnkoGo123: 很正常,rust目前的标准库优化不如go,当然还有其他方面,如果不是go有gc,rust赢过go的几率几乎为0,也就是rust的性能一定会比cpp慢一点,无gc的go其实速度跟cpp应该是一样快的

ankoGo 2024-04-07 13:29

从楼主的口吻来看,似乎很质疑人家,但是自己又提不出任何更有效的方案!

ankoGo 2024-04-07 13:28

很正常,rust目前的标准库优化不如go,当然还有其他方面,如果不是go有gc,rust赢过go的几率几乎为0,也就是rust的性能一定会比cpp慢一点,无gc的go其实速度跟cpp应该是一样快的

TinusgragLin 2024-04-06 11:51

哈哈哈,确实,这个文章的标题就有点标题党那味儿了,不过内容确实是干货。说起来,我觉得以后新社区可以搞个文章分享专区,过去某段不堪回首的经历告诉我,一篇藏在某个互联网角落里的好文章真的可以抵得上好几天的搜索[苦笑]。

--
👇
lithbitren: 😂😂😂人家原文标题里自己这么写的,然后还在总结里写了一些理由和性能优化的难点,而且性能比较的肯定是基于某语言环境下的最终性能,抠字眼没啥意思。

--
👇
TinusgragLin: 据我所知,Rust 和 Go 语言从语言本体层面上都没有设计针对 protobuf 的解码/译码库,楼主是不是看错了?

作者 lithbitren 2024-04-06 10:26

语言层面性能rust肯定赢,应用方面也是基于语言层面性能来进一步优化的,绝大多数情况下,都是rust开发的应用性能最佳,少数不是的当然要拿出来说道说道,说不定就能找到更好的优化思路了。

语言层面的rust爽文还是很少的,毕竟基本都是rust赢赢赢。只记得有一次多重循环计算julia竟然赢了rust,后来才被大佬发现性能瓶颈竟然是跨循环调用变量导致的,只要每次把父循环的变量复制到子循环里变成更小的局域变量就行了,虽然代码啰嗦了点,但性能还是赢了。

作者 lithbitren 2024-04-06 10:03

😂😂😂人家原文标题里自己这么写的,然后还在总结里写了一些理由和性能优化的难点,而且性能比较的肯定是基于某语言环境下的最终性能,抠字眼没啥意思。

--
👇
TinusgragLin: 据我所知,Rust 和 Go 语言从语言本体层面上都没有设计针对 protobuf 的解码/译码库,楼主是不是看错了?

Bai-Jinlin 2024-04-06 09:55

假:rust输给go

真:一个第三方库输给了优化的更好的第三方库

别什么都上升到语言比较

TinusgragLin 2024-04-06 09:04

看了一下文章,应该是从 VictoriaMetrics 这个 Go 库领先的解码性能开文,讨论对 prost,rust-protobuf,bytes 这些 Rust 库本体的设计优化和对耦合这些库的开销的优化。我自己感觉文章后面对 bytes::Bytes 的优化,感觉会在需要输出 zero-copy 解码后的结构的场合很有用,学习了!

1 2 共 21 条评论, 2 页