前言
今天是 2025-02-20,Boost 1.88.0 还没发布,但目前的版本在实现 RegameDesk 时遇到一些问题,导致使用了不优雅的解决方案,按照稣和作者们的沟通,下个版本都能解决,所以稣认为 1.88.0 才是适合远程桌面的 Boost 版本。
Why Boost?
在开发过程中,选择一种基础库或库的集合(注:实际上 Boost 是一个集合)几乎是必然的。如果您的产品使用了 Qt,那么许多基础功能很可能会直接借助 Qt 来实现。有些项目可能会选择 Google 的代码作为基础,从而引入 Abseil。甚至还有一些团队会单独提取 Chromium 的 base 模块来使用。
稣曾遇到过有人推荐使用 Folly,而 Folly 本身也依赖于 Boost。如果您能够接受 Folly,那么当团队不再使用它时,接受 Boost 也应该不是问题。
以上例子其实暗示了一个事实:C++ 标准库的功能相对有限,难以满足实际项目的需求。为了解决这一问题,开发团队通常会选择引入第三方库。在选择第三方库时,主要有两种思路:一种是引入一个功能强大且尽可能全面的大型库(集合),再配合少数其它必要的小型库,以最大化地保持代码风格的一致性;另一种则是引入多个专门解决特定需求的小型库,这种方式虽然可以让每个库都“小而美”,但可能会导致代码风格的不一致。选择哪种方式其实很简单——选择您最熟悉的那一种。
注意!上一段说的“小而美”,从整体上看,可能是假象,尤其当项目很大、成员较多时。当然您可以提出 Chromium 来反驳,不过您需要一定实力和精力去驾驭,所以稣只是说“可能”!
对稣来说,Boost 是一个显而易见的选择。它经过多年的发展,积累了丰富的文档和社区讨论,学习和使用难度都不大。过去有人抱怨 Boost 的编译时间过长,现在早已不存在。而且在如今普遍配备 64GB 内存、高速 SSD 的开发环境中,加载大量头文件已经不再是问题,怪罪 Boost 使工程加载变慢的人也能放心了。
片面地安利 Boost
使用 Boost 相比自己实现而言,有以下好处:
-
开发更快;
-
运行更快;
-
运行更稳;
-
代码可读性更高。
后面会举真实例子说明为啥是和自己实现比!先说事实,以上三条总有 1~2 条符合,甚至对于某些团队——可能是中 3~4 条。
首先,开发更快,可能是最有争议的,很多人会反驳说——光学它就要很多时间。这要是放在以前,稣可能想不出啥好招给这部分人洗脑,现在有大语言模型,各种辅助手段,如果还这么说,完全也不用去反驳,没必要了。
另外,Boost 有部分库确实性能不行,并且官方文档也是明说的,这种情况是求稳定,比如 Boost.Format。
剩下的,Boost 通常有十分优秀的性能,除非极端的具体领域优化,不然大多数人能把性能写赢 Boost 的概率几乎是 1%(多给 1 分,怕您是真大佬!)。举个例子,Boost.JSON 的性能是高于 RapidJSON 的。RapidJSON 这名字起得好(快),不一定就是真的好(快)。
等等,第 4 条是怎么回事?有些人会说他自己手撸的更好理解,如何反驳?嗯,很可能只是对于作者本人才更好理解,别人看都不想看(笑)。作为团队合作的产物,更多共同点才是好的。比如说,整个团队都熟悉 STL,那么基于 STL 的接口/实现就不会差,而把它等价地改为基于某个第三方库,如果没有强力的理由,通常会被(不用脑地)认为不好。自己写的,对别人来说,何尝不是一种“第三方”?显然,大家普遍认可的“第三方”才可能是更好沟通的,更好达成共识的。(注:这里的“大家”是普遍意义上的大家,不是说某个团队里的少数几名成员,毕竟有的团队就两名写代码的,并不存在“多数”和“少数”!)
例子
大家最喜欢的案例分析来了……稣正好遇到这样一个活生生的例子:实现一个 IPC 用于 Service 和工作进程之间通信。
这个故事发生在雪蛤油打工时。一开始,稣就打算使用 Boost 封装的 Pipe,因为以前干过类似的活,有成功案例。但不幸的是,稣是第二个加入团队的,原来已经有人弄过一个实现,纯手撸的,基于共享内存和事件通知。关键是,大佬说这实现在他前公司用了 2 年很稳定。稣想了一下,虽然自己的实现代码量不到它的 1/5,但只接受了几周的考验。还是别冒险,于是那份手撸版本上了生产。
然后有一个周末,没回家,随手拿 example 改改对比性能,使用 Boost 的版本速度居然是那手撸实现的 4 倍!在应用层,共享内存是 Windows 上最快的 IPC 机制没错,但它需要其它内核对象的辅助,最终完成时速度就拖慢了。Boost 使用 Pipe 作为 IPC 机制,而没用共享内存和事件通知复合实现,很可能作者是知道这门道的。
对了,每次发送多少字节对性能是有影响的,如果您打算测试,需要对不同大小的信息进行测试,不能用固定的大小,以免得出不全面的结论。
总结
本文,乃至本系列文章,重点在于心法,并没打算详细介绍项目里用了 Boost 具体哪些类库。因为很简单的道理:您要的功能,如果 Boost 有,考虑用它即可。
看到这里,如果您还记得稣写的基于 Boost 的 IPC 代码,它又多接受了三个月的考验——极其稳定,重点是它用起来简单多了。