性能优化中的有损思想

31 阅读3分钟

性能优化中的一种思路是“有损”思想。其核心思想是“刚刚好满足需要就好”。隐含的思想就是“挖掘出需求真正的下限要求”。无论是系统功能还是业务功能上的需求,往往只考虑“能否实现”,而很少会考虑“最低限度下的实现”。当需要进行性能优化时,可使用此思路,通过挖掘该需求的最低限度下的实现来降低对系统资源的需求,以间接提升性能。

是不是有点抽象?我们用大白话解释一下。现实中,如果旁边有人问你现在几点了,你可能会回答“5点半了”, “快8点了”, “7点50”; 但很少会有人说现在是“北京时间2023年8月28日20点20分30秒”。 再比如别人问,这里去地铁站还有多远?你会回答“差不多4、5百米吧”、“走路10分钟就到了”,也是个误差比较明显的回答。 为什么呢?因为我们非常明确地知道,这人的需求一定只是得知一个大体的结果。这就是从日常生活里已经提前“挖掘出了下限要求”

下面再举几个代码里的示例。

例一:当前时间

获取当前时间是个很常用的操作。它能获取到当前的精确时间,精确到纳纱。但你真的需要这么精确吗?按我的经验,至少90%只需要精确到毫秒,甚至一大半都只需要精确到秒级。这时“挖掘出需求真正的下限要求”就是找到能满足功能需要的最低时间精度。

尽管有 vDSO​的存在,使得获取当前时间的系统调用性能也非常高,但这也是一种资源浪费。

一种可行的思路:后台任务每毫秒执行一次,缓存当前时间,取用缓存的时间作为当前时间。

例二:浮点数精度

有时我们需要对两个浮点数进行计算,但并不需要用到准确的结果,而只是需要知道前N位甚至只需要知道它的数量级。

这时可以把浮点数计算变成整数计算,其精度自然会有损失,但计算性能也提升了。

例三:缓存更新的实时性

有些产品需求会要求“当数据更新时,缓存需要立刻同步”。而稍有经验的人都知道,缓存更新的实时性越高,对缓存系统实现的要求就越高——更复杂也更耗系统资源。

但“立刻”到底是指多少呢?1秒以内能接受吗? 5秒内可以吗? 1分钟以内可以吗? 继续追问下去,直到能找到一个最宽限的同步时间。

例四: 更慢但更便宜的系统

在能满足需求和用户体验的前提下,降低系统配置,或使用更便宜但更慢的数据库(比如内存型缓存换成SSD缓存),最终实现成本的节省。毕竟性能优化最重要的目的就是成本优化。

例五: TopK

一个很常见的需求是从N个元素里取出Top K个。

如果实现方法是对这N个元素进行全排序,再取前K个,就浪费了。因为根本不需要完全排序,有多种算法可以在不完全排序的情况下只取到前K个(TopK也算是八股算法题里面的高频题了)。

常见的实现如最小堆、部分快速排序。由于本文主题不是讲八股,因此不详说了,可自行搜索"TopK"相关算法题。