聊一下代码的虚胖

导读:

代码“虚胖”,或者叫“代码膨胀”,似乎是时代发展背景下不可避免的一个产物,在不同的时代,无论是在资源贫瘠的上上世纪,还是不差钱的21世纪,在各自的时代背景下都有不同争议。今天,我们来聊一下代码“虚胖”。

记得刚入行时,带我入门的师傅经常“吹牛”说,公司的某个现场用6行存储过程实现了计费的批价功能,当然那时刚入行的我只觉得高深莫测,没敢问细节。许多年后,有个同事跟我抱怨说:你写的代码我都看不懂,一层套一层,跟个套娃似的。这值得反思,我们的代码从什么时候开始变“胖”了呢?

CPU和内存有限的时代似乎才是编程的黄金时代

首先,何为“代码膨胀”?大概有2个意思,一个是无效代码,一个是低效代码。比尔盖茨曾经说过:再复杂的事,64K内存也应该够了。那个时代信奉用最少的代码做最多的事情,最早的DOS系统只用三个最基本的文件就能运行;游戏界的传奇游戏《魂斗罗》只有28K大小,而运行它只需要2KB内存,32K的超级玛丽玩得飞起。还记得曾经玩过一个小霸王游戏《吞食天地2》,游戏里有对话系统、*器武**系统、策略系统,而且还有很长的剧情,才600K。而以现在大家最熟悉的微信为例,2011年发布的微信1.0版本,安卓APK安装包的体积仅457KB,还没有一张照片体积大,解压后也只有737KB,占用空间1.03MB,文件数也只有199个。到了2022年6月发布的微信8.0.24版本,安卓APK安装包的体积已经膨胀到了257MB,11年的时间膨胀了575倍。也就是说,最初的微信1.0仅用199个文件就实现了“聊天”这个核心功能,当然它的膨胀是有原因的,我们后面再一一分析。

不可否认的是,随着硬件的提升,一切都在慢慢膨胀,当年手机只有2G内存时,软件比例占60%,后来4G内存了,还是60%,到现在8G内存甚至更高,占比也在50%以上。从这方面看起来,CPU和内存有限的时代确实是编程的黄金时代。

现代商业思维的引导?

那什么改变了这一切呢?软件商业化的出现是一个引子,商业的本质是为了银子。如果用64K就解决了64G的问题,外行的客户难免会想,这些人有没有认真做事?假设我们要设计一款高靠背的沙发,我们需要跟客人解释,高靠背的沙发为什么要靠墙,是因为重心可能不稳。但是客户会说,他会很小心,还会做好固定等等……解释了半天,最终回到原点。同样的道理,如果我们用高效去解释为什么用那么简单的代码来实现,客户可能难以理解。他们会认为:代码量的大小决定了功能差异,代码量大功能一定会更强,200M的程序一定会比20K的像样,客户不会理解这是代码低效引起的。有人会想,我们去解释清楚不就好了。但是那意味着你得把整个底层框架解释一个遍,客户没有这个耐心,我们也没有这个时间成本。

商业化的软件开发,普遍利益最先,效率放其次,还要考虑客户需求,考虑流量变现。比如说广告更新,VIP验证、客户使用习惯收集、充值入口等等,这也成了“代码膨胀”的成长沃土。“代码膨胀”的另一个重要原因也与商业息息相关,即存储介质容量的快速增长。曾经的程序员需要冥思苦想怎么样让一段代码既能完成20个功能,又可以塞进一个容量仅有5.4MB的闪存里。毕竟一个苹果微型机只有1.2M软盘,总内存只有几百K,还要加系统和汉字字库,给程序的空间还有多少,代码不行,机器根本不能加载。而在今天,他所思考的仅仅是如何让一段代码能够完成20个功能,至于所占空间,抱歉,代码升级,请拓展您的设备容量!

“内存杀手”的独白

在IT界,一直有软件正在统领世界的说法,大概意思是以后这个世界会越来越依赖软件的应用和服务。软件相对于硬件而言,比如说电脑和手机,没有软件的驱动,那确实是没有多少价值。软件是由代码构造而成,从游戏到直播,从聊天工具到交易软件,所有这一切的背后都是由程序员写出来的代码在支撑,那代码的质量往往决定了软件的水平。随着代码的膨胀,“内存杀手”应运而生。

我们继续聊微信,现在手机头号内存杀手应该就是微信。微信的数据可以分成三类:缓存、聊天记录和其他数据,其他数据包括主程序、程序文件、资源文件、其他账号聊天数据等等。微信的聊天记录、图片、文件,甚至包括公众号推送信息都存储在本地,不像QQ的聊天记录都存储在云端漫游。在清理掉聊天记录之后,仍会有超过20G的数据存留。这从侧面也反映了一个问题,相对于微信体积的膨胀而言,微信的功能也在膨胀,从一个“小而美”的简单即时通讯APP,已经成为了一个集社交、娱乐、工作、出行、购物、生活、金融等成百上千项功能服务于一体的超级APP,聊天变成了其最基本的功能,光是微信服务页的功能包括金融理财、生活服务、交通出行、购物消费等4大类20多项,微信发现页的功能也有包括朋友圈、视频号、直播、购物、小程序等10多项内容。在功能“大而肥”的情况下,再做到“小而美”很难。其他的手机应用也是如此,单一功能的APP早就在时代的洪流中被淘汰了。支付宝、京东、淘宝、抖音、小红书等热门软件,在应用商店中标注的大小都超过了100M,而实际安装后的大小肯定要超过100M,手机应用动辄300/400MB+已是常态,甚至打个字都需要508MB内存(微信键盘)。(小编的王者荣耀有12G,每次赛季更新都在极限的边缘徘徊,犹豫着该卸载哪个APP,纠结啊~)

这是一个不得不做的选择题,我们可能需要一个A,但是键盘上有26个字母,还有一大堆用不上的按键,造一个只有A的键盘成本和造一个完整键盘的成本是人们要做的选择。百分之一是聪明人的选择,百分之九十九的“废物”堆积是智慧人的选择,聪明的选择未必能从市场上活下来,而智慧的选择一定能够活下来,你会选哪个?

代码精简和商业权衡

做软件行业的,几乎都会遇到一种情况:没有源代码控制,也从未删除任何代码,只是不停地加东西,原因可能是因为删除东西会有风险,最后代码越来越膨胀。刘慈欣在《赡养上帝》中举过一个例子,上帝们科技十分发达,飞船都是智能化的,但是上帝们的技术能力在享受中被遗忘了,智能机器人维护的程序代码运行多年以后,原来越繁杂,以至后来无法运行。这说明了代码精简的必要性,但一个人思考问题,除了大脑,还需要心肝脾肺肾、胳膊腿之类的。就像做一个游戏,代码越短越好,实现了游戏功能,但是游戏要穿衣服,要包装,要保护,要自我检修,可能还要个后门。1%的代码完成了80%的场景覆盖,还需要另外的99%用来兼容和处理各种异常。尽管那99%大多数时间都归于无用的“垃圾”之列,但正是这些看似没用的“垃圾”代码,可能会让软件在某一刻免于崩溃。

所以,首先我们要达成一个共识:在功能效果一样的情况下,代码越少,逻辑越快,反应也越快,并非是单纯说代码写得越少越好。软著低于3000行代码是不批的,同理作品出版也有字数要求,这是发展过程中的问题。在软件领域,顶级高手和普通程序员之间的差距就在于,用同样的编程语言,后者写出来很多代码都解决不了的问题,前者可能也就是一顿饭的功夫就能解决。“码农”敲的是累赘的代码,“码帝”大部分时间在思考内在逻辑。这就是程序员修的境界,短短几句的代码里,要有最完美的逻辑和最精妙的算法,外修语言,内修算法。以数据为根,算天算地算自己。

代码精简和商业权衡的关键在于“环境”,这是“楚王好细腰,宫中多饿死”的道理。王兴曾在网上感慨道:“据说一辆宝马X5里的软件代码有3亿行,一辆特斯拉只要1000万行,真是令人绝望的差距。”很类似的还有2008年时塞班和iOS的代码行数差别。还有“不懂技术”的华为老板任正非也曾谈到过代码这个事:“有一个小伙子把230万行代码降到90万行,这不就节约了140万行吗?那可以拿出70万行来激励啊,以此激活组织。”在科技层面上,现在的设备性能太好,运营一万行和一行给客户的感觉差不多,再加上优化程序会增加成本,很多时候甲方选择看起来好而便宜的一万行,而忽略货真价实的一行;在社会层面上,国内的环境都在鼓吹35岁以上下岗,而通常的代码高手都是时间沉淀下来的(天才除外,但天才能有几个)。技术想要进一步就必须学会妥协,代码精简也并不能一步到位。代码精简确实是个好东西,但是面对众多的操作系统,利于维护也同样很重要,太精简的代码如果只有作者才能看懂,谁来维护呢?

伟力汇聚于个体

这个世界,就如同一条永远流淌的长河。我们在长河中,如同水中的鱼,懵懵懂懂,随着河流前进的方向而去。偶尔,鱼群中会出现一两条特别强壮的大鱼,奋力一跃,跃出水面。复制黏贴,人类的学习模式大部分是这样;然而跳出水面的个别鱼儿,看到了远方的风景,于是开始特立独行、自我探索、深度挖掘。当独行者的力量开始影响世界时,就能引领潮流,就如Linus Torvalds之于Linus,丹尼斯·里奇之于C语言,乔布斯之于苹果。历史上“徙木立信”的故事,就是这个道理。人们因看到而相信,就像萤火虫本能地向光靠近。代码精简之道亦是如此,因势利导,顺势而为,以个人激发群体,即便是商业也会遵从于流行趋势。当代码精简大行其道时,“代码膨胀”自然就失去了存在的空间,这是代码精简的另一条大道。

结语

以前的古诗意境很美,文言文也是言简意赅,而现在的小说,要用几百上千个字来表达以前的几十个字,这是时代的选择,时代会在合适的时间选择它认为合适的方向。人类作为食物链的顶端,只要本心不变,本意不违,总是能得到一个最优解。

作者简介:

王亚冰,亚信软件工程师,做过几年计费,玩过几年BI,因拙于口,故而勤于笔。朋友不少,圈子很广,对世界永远保持着一份好奇心。

信奉格言:In a world of locked rooms , the man with the key is king.