网络架构之路(二):性能

我们在上一篇博客中设定了架构的目标,只有一个,就是可维护性。完全没有提性能,这是故意的。

似乎程序员都是急性子,或许是被windows冗长的开机时间折磨够了,有可能是因为提升性能的效果是最显而易见的……总之,我发现,绝大部分程序员对性能的关注和热情是无与伦比的!

C#刚刚推出的时候,就有人摇头晃脑的说,“嗯,自动垃圾回收,性能不行吧?”

DataSet横空出世,马上有很多人写代码,在DataSet里插入几百万条数据,证明DataSet的性能问题

Linq当然更要被骂了,尼玛用反射?反射是什么,同学们知道么?性能大老虎呀!更不用说那些自动生成的sql了,有我手写的高效么?

……

所以直到今天,我仍然看到很多程序员无怨无悔的用存储过程来构建他们的系统,一个存储过程可以有几千行!然后,他们很无辜的问,“业务层有什么用?究竟能干些什么呢?”

在带团队的时候,我最怕讲的就是性能有关的问题。你要是不谈性能呢,那代码有时候真心看不下去;你要是强调性能呢,不知道他会给你整出什么幺蛾子出来。其实这就是一个“度”的掌握,所以非常难以用语言予以表示清楚。所以无数次挫败之后,我只好咬牙切齿的说,“你的代码,只有一个评判标准,可维护性。性能的问题先不管!”这个答案似乎并不能服众——尤其是对有上进心的程序员而言。

所以,我先专篇讲性能,希望能帮助大家更清楚的认识这个问题。

一、性能不是不重要,而是他没有可维护性重要。要理解这一点,首先要理解可维护性的重要(请再读上一篇我花数周找bug的段子);然后要明白:解决性能问题,我们可以有很多代码以外行之有效的方法,而可维护性基本上就只能靠代码了;最后,还是要牢记:没有牺牲,就没有胜利!

二、所以,在绝大多数情况下,当性能和可维护性相冲突的时候,性能让位于可维护性。我们采用其他办法来弥补代码性能不够高的问题。

空洞的说教没有意义。我们还是举例来说明吧!

破坏可读性

前段时间我review代码的时候发现,这个程序员用Linq之后老是用First()而不是Single(),我就奇怪了,按业务逻辑,返回的值就应该是一个,难道可能会是多个,多个应报异常,不应该取First()就完事了呀?想了一会儿,问这个程序员,他的回答让我瞬间一种无力感,“First()性能更高呀!”以下为对话实录:

“你怎么知道First()性能更高呢?”我问。

“First()嘛,取了第一个合格的值就返回,就不会继续查下去了;Single()的话,就会一直查,查出所有数据,然后再取其中的一个。”

“你确定?你知道有一种东西叫做索引不?”

“啊?……”

然后我简单的告诉他,索引是一种树状结构,可以让查询更快等等。

“但我还是觉得应该用First()”,他想了一会儿,还是很坚定。

“为什么?”,我不明白了。

“就算有索引加快了查询速度,但用First()在加快了速度上更快呀!更快总是没错的吧?”

“……”,我真不知道该怎么说了,最后突然灵光一闪,“好吧,那你说说,微软为什么要搞一个Single()方法出来呢?就为了搞出来误导你们?让用First()的产生优越感,嘲笑用Single()的?”

他陷入了沉思。

我刚入行的时候,还很是收藏了几篇文章,比如《高性能编程的十大准则》之类的,里面的内容大致就是,“总是使用StringBuilder,不要使用‘+’;总是使用……,不要使用……”。这类文章下面总是有一堆人叫好,“不错!”,“谢谢分享!”但慢慢的,我就对这些文章产生了怀疑(也应该感谢园子里的老赵,csdn里面的sp1234之类的大神);直到很后来,我才明白为什么这种说法是肤浅的;而只有通过上面的对话,我才能清晰的把我的理解说出来。

所有这些牺牲性能的简单封装,都是有其目的的;而其中一个很重要的目的,就是为了提高可读性。你为了性能,故意不使用这些现成的封装,通常,丧失的就是可读性。

想当然

继续上面这个例子。最开始的时候,这个程序员关于性能的考虑其实是想当然的。这种想当然的情形很多,大致有这几种:

自己的理解完全就是错的

自己的理解不能算错,但实际上底层已经对该问题做了优化

自己的理解没错,底层也没优化

第1、2种比较好理解,第3种为什么也说他“想当然”呢?因为没有和硬件环境相契合。

最简单的例子就是“缓存”。比如面试的时候,问你一个问题,“缓存能不能提高性能?”请注意,这是一个陷阱。答案应该是:“不一定”。几乎所有的人都认为,缓存可以迅速改善性能,是因为今天计算机的CPU和磁盘运行速度,远跟不上内存的发展。但即使如此,无节制的缓存,一样可以拖垮整个系统。

类似的例子还有很多。你沾沾自喜,我节约了一次磁盘读写的时候,你同时增加了CPU的负荷;你优化了算法,减少了CPU的运算,但其实增加了内存的压力……天下没有免费的午餐。同样的代码,随着数据的增加,硬件的改变,会呈现出截然不同的性能表现。

所以,开发过程中,很多的“优化”,其实只是你的想当然。与其这样想当然的优化,不如在拿到性能测试结果之后再有的放矢的进行优化。这时候,又回到了我们之前说的,是不是代码的可读性更重要?这样你才能迅速的找到该优化的瓶颈啊!否则,一堆乱七八糟看都看不懂的代码,你怎么去优化,你连该优化的点都找不到。

难以维护

另一个搞笑的例子是关于我自己的。创业家园项目里有一个功能:显示博客正文的同时提供一个上一页下一页的链接。惯常的做法就是直接在数据库里查就是了,但我总觉得不对,这样做两次查询有必要么?能不能优化?于是我想到了一个“绝妙”的点子:为什么不直接在博客里存储上一篇和下一篇的Id呢?这样我一次性数据往返就能取到所有数据了嘛!各位同学是不是觉得我这个主意很棒?

噩梦由此开始了。

首先,我们是想在发布博客的时候,设置他的上一篇和下一篇。但是,上一篇好设置,下一篇呢?还没有啊!怎么弄,就只好在博客发布的时候,设置他的前一篇,同时设置他前一篇的后一篇。

然后,我们新添加了一个功能,除了上一篇下一篇以外,还需要在当前博客所在分类中的上一篇和下一篇。怎么办?再加字段呗。所以,博客里就有了Previous, PreviousInCategory, Next, NextInCategory。这时候,就感觉到有点不妥,但还可以接受。

接着,出现了一个问题,上一篇下一篇博客被删除了,怎么办?这个过程,就相当于从一个双向链表里移出一个节点一样麻烦。头开始有点大了。

再接着,博客除了发布删除以外,还有各种其他状态,比如被屏蔽。而且被屏蔽之后,能否显示和当前用户又有关系。当前用户是普通用户,不能阅读;当前用户是作者自己,就能够阅读。怎么办?首先,屏蔽的时候,要设置上一篇下一篇;屏蔽取消的时候,还是要设置上一篇下一篇。然后,上一篇下一篇得根据当前用户不同变化的这个问题,基本上就傻眼了……

最后流着泪把辛辛苦苦折腾了好久的代码全改回来,就通过数据库查呗,多么清晰简洁的逻辑啊!性能问题?首先,这样做造成了性能问题么?然后,就算有问题,用一个缓存能解决不?

合理浪费堆硬件

说了这么多,不知道有没有引起同学们的反思。可能大家还是过不去心里那道坎:明明有一种性能更高的方法我们为什么不用?

因为浪费呗!

什么?你有没有搞错?我的代码,至少省了一块内存条!那是你还没从“穷学生”的角色里转换过来。你花一周的时间对代码进行了优化(就先不考虑你的优化带来的维护成本增加了),为老板省下了一块内存条的钱。你以为老板会拍着你的肩膀表扬你么?老板打不死你!

兄弟,账不是你那样算的。当你是学生的时候,你的时间成本是0;但你进入工作岗位,每一天都是要发工资的。

通过代码来调高性能,是一种无奈——对硬件性能不够的妥协(参考:80年代游戏开发者的辛苦困境。这样写性能就高,但为什么现在没有谁再这么写代码了?)。否则,绝大多数情况下,堆硬件比优化代码的效果好得多,而且便宜得多。硬件的成本按摩尔定律往下降,我们程序员的工资也能按摩尔定律减么?

明明window 10 比window 95更耗性能,为什么今天没人用window 95?为什么VS 2013要10G的空间我们都还屁颠屁颠的赶紧装上?为什么现在大家都用C#,没人用汇编?我们站在人类文明积累的今天,就应该理所当然的享受这一切成果。有打火机你不用,你要钻木取火。如果你是因为要学贝爷荒野求生装逼,可以理解;如果你说你是因为怕浪费天然气,我……我……我怎么说你呢?“给做打火机的一条活路,行不?”同样的,程序员大神同学,你就当做好事,给下面写底层做硬件的一条活路吧!你的代码都是010001000010000001010101……了,你让其他人怎么活啊?

最后,我突然想到的一个程序员为什么对性能如此敏感疯狂,对可维护性毫不在意的一个可能原因:

性能很好理解,卡得要死和跑得飞快;可维护性很不好理解,至少得跑个两三年才能体现,那时候,谁知道爷在哪里偷着乐呢

性能上不来,程序员只有羞愧的低着头,都是我的错;需求有变更,开口就骂,“哪个SB又要改……”;

大家觉得是不是这样的?所以,愿意把代码百炼成钢绕指柔的人少。想来,是一种莫名的悲哀和凄凉。

最后最后,有一些我能想到的名言警句供大家参详:

过早的优化是万恶之源

优化首先需要找到性能“瓶颈”。否则,任何人都可以随手一指,“这段代码需要优化”。

可读性更强的代码总是更好优化

硬件永远比软件便宜

作者:自由飞

来源:51CTO

时间: 2024-10-06 12:31:20

网络架构之路(二):性能的相关文章

网络架构之路(三) 单元测试

在带队的过程中,性能的问题还比较好解决,最消极的想法,"好啊,多一事不如少一事,你让我不管还不简单?",但要求写测试代码,那就炸锅了!以我的经历,"测试驱动"是一个最具争议的话题,没有之一.吹捧者和反对者泾渭分明,而且都有大量的论据和证明.记得博客园曾经有一篇文章,大意是:"公司付钱给你不是让你写测试代码的",下面一片狂赞. 在我自己的项目开始的时候,我是放弃了测试驱动的,里面总结得很准确,最大的原因是"懒".但最后让我下定决

CloudRAN:无线网络架构云化之路

华为无线网络产品线首席营销官杨超斌. 今天,谁都无法否认云对于网络架构演进的价值.但问题是如何利用云来重构无线网络架构?在2016年华为全球分析师大会上,华为率先在业界发布了CloudRAN解决方案,从而在这股无线网络架构云化潮流中占得了先机. 无线网络架构的云化,与数字化转型密不可分."无线产业从现在到未来五年,将经历面向全行业数字化转型大背景下的基础互联能力的重构."华为无线网络产品线首席营销官杨超斌表示,"CloudRAN实现了从拓扑到资源分布完全弹性的新网络架构,从而

赵慧玲:网络重构之路漫长,SDNFV挑战诸多

4月18日,2017全球未来网络发展峰会SDN/NFV技术与应用论坛于南京江宁隆重召开.会上,中国通信学会常务理事赵慧玲发表了"SDNFV实践与挑战"的主题演讲.赵慧玲表示,网络重构的主要挑战涉及网络层面和运营层面,其中网络层面主要涉及SDN和NFV,而运营层面主要包括网络编排和业务编排两大方面. 据悉,Gartner技术成熟度曲线表明,SDN/NFV已经趋近成熟.数据显示2015到2016年间,运营商采用x86的服务器中47%用于SDN/NFV(OSS/BSS占29%,云关联服务占1

买单侠数据库架构之路

摘要:在2017杭州云栖大会阿里云HTAP技术专场上,上海秦苍信息科技有限公司DBA负责人赵怀刚为大家分享了HTPA型数据库产品在现实中的落地应用以及企业级数据库架构设计中的HTPA的应用. 本文内容根据嘉宾演讲视频以及PPT整理而成. 本次分享的主题是买单侠数据库架构之路.秦苍科技是一家互联网消费金融公司,我们所有的产品基本都是托管在阿里云上的,在自己的系统中大概应用了20多种阿里云数据库产品.基于阿里云平台,秦苍科技的数据库架构与传统RDS数据运维相比存在着本质的区别.接下来着重介绍一下在产

云栖大会分享:买单侠的数据库架构之路

互联网金融行业快速发展的浪潮中,面对海量增长的数据,买单侠走出了自己的数据库架构之路. 本文是买单侠DBA负责人赵怀刚在杭州云栖大会上的分享,介绍了数据库运维中遇到的问题.基于阿里云平台数据库架构的演变和案例和云数据库运维的思考.图1 赵怀刚在分享 秦苍科技是一家专注于为年轻人提供消费分期服务互联网消费金融公司,目前有"买单侠"和"星计划"系列产品,"买单侠"面向中国年轻蓝领用户,提供移动端消费分期服务."星计划"为年轻女性用

BaaS后端即服务 - 通往中台架构之路

该文章来自阿里巴巴技术协会(ATA)精选集 BaaS代表第二代云服务,相对于AWS.阿里云等公有云(IaaS,PaaS)是第一代云服务,通过广泛部署云数据中心解决了开发和运维系统不需要管理服务器的问题,BaaS则在第一代公有云数据中心基础之上,对云计算资源进一步封装.简化与优化,提供开发.运维和服务的一站式云服务. 这就是所谓BaaS(后端即服务)模式的兴起,BaaS将公有云数据中心资源根据前端应用场景打包,通过简化的调用接口提供给开发者使用.通过减负,开发者得以集中精力于用户的研究.APP软件

新浪微博千万级规模高性能、高并发的网络架构经验分享

[本文转载自新浪微博千万级规模高性能.高并发的网络架构经验分享] 架构以及我理解中架构的本质 在开始谈我对架构本质的理解之前,先谈谈对今天技术沙龙主题的个人见解,千万级规模的网站感觉数量级是非常大的,对这个数量级我们战略上要重视它,战术上又要藐视它. 先举个例子感受一下千万级到底是什么数量级?现在很流行的优步(Uber),从媒体公布的信息看,它每天接单量平均在百万左右, 假如每天有10个小时的服务时间,平均QPS只有30左右.对于一个后台服务器,单机的平均QPS可以到达800-1000,单独看写

千万级规模高性能、高并发的网络架构经验分享

千万级规模高性能.高并发的网络架构经验分享 主 题 :INTO100沙龙时间 :2015年11月21日下午地点 :梦想加联合办公空间分享人:卫向军(毕业于北京邮电大学,现任微博平台架构师,先后在微软.金山云.新浪微博从事技术研发工作,专注于系统架构设计.音视频通讯系统.分布式文件系统和数据挖掘等领域.) 架构以及我理解中架构的本质 在开始谈我对架构本质的理解之前,先谈谈对今天技术沙龙主题的个人见解,千万级规模的网站感觉数量级是非常大的,对这个数量级我们战略上 要重 视 它 , 战术上又 要 藐

应对云业务挑战:数据中心网络架构的新思考

现代科技的成果使得人类的器官在空间上得到了极大地延伸,如果说电话是人类声觉的延伸.电视是人类视觉的延伸.数据中心是人类大脑的延伸,那么网络则是各种延伸物之间.以及延伸物与主体之间相互交换信息.传达指令的神经系统.正常的神经系统是一个健康人类的基本标志之一,同样,大带宽.低时延.高可靠的网络系统也是使得人类各种器官得以有效地延伸.进入云时代的基本保证. 云业务对网络的挑战 随着信息业务进入云时代,越来越多的用户通过各种不同类型的业务设备进入到网络之中,各种业务设备之间.众多用户之间所交换的信息量在