(工作感触)工作中“优化方案”有感

在工作隔三差五就会有优化方案。谈起这个宏大的命题,有人呵呵了,有人吐槽只想推翻一切重构,还有人是巴拉巴拉漫谈边际!最近读到一些工作感触的文章,感触颇深。。

如果单说优化,在我工作期间也有一段不知所措的时期,感觉胡子眉毛都一把抓了。然而它确实是你升职加薪的必备弹药,出彩的地方。特别是在大公司。

那么我们用理科特有逻辑性来走一遭。下面摘自原文  有些地方修改了点。

什么是优化

首先我们先破题,来谈谈“优化”这个事情。通常情况下,我们说到优化的时候,往往会伴随着对之前系统的吐槽。或是不好用,或是性能低,或是用起来很麻烦。巴拉巴拉。是的,当我们对原先的系统有槽点的时候,我们会谈到“优化”。而“优化”的前提也是,之前已经有过一个东西存在,而且真对目前的场景应景不再适合。这个是有需要对原有系统进行调整,以满足当前的场景与需求。那么所谓优化即是:对原有系统进行有目的的改造。

好吧,这听起来虽然说了什么,但其实什么都没说。因为这是一句大实话。

but,我们仔细分析一下,我们要进行优化必须能够:

对原有系统的问题有所了解

了解目前场景和需求

有目的性的改造原有系统

我们来说一个我们通常会遇到的例子,也是在面试的时候会遇到的问题–“UItableView的性能优化”。其实每次有人问我这个问题,我内心都有千万只“草泥马”奔腾而过。没有具体的问题场景,只单单跑出来这样一个问题。是可以和他扯什么图片内存缓存了,避免圆角的使用了,预渲染,预加载了之类的东西。但是这些东西,真的对于在解决他们TableView卡顿的问题有效吗,不见得。套用《安娜卡列尼娜》一句话:

流畅的UItableView都是相似的,不流畅的UItableView各有各的不幸。

好了,吐槽到此为止。吐槽的目的是为了说明一点,你要进行优化,必须有一个特定的场景。在一个受限的范围内进行优化,因为这样目的是可控的。漫无边际的优化,和别人基于方法论的建议之类的东西,不一定对当前的问题有帮助。

比如,之前我们在做的一个社交类的App中,首页使用了UItableView,老板说怎么用着这么卡顿。然后我们就开始了“优化”。

首先,我们知道我们要优化的是第一个tab的tableview的滑动效率的问题。那总得有个监控的指标吧。对于程序猿来说,感觉这个不卡了,或者感觉这个卡,这个东西太模糊了。无法衡量啊。所以一定要量化。对于界面来讲就是大家常说的FPS,每秒帧率。于是我们测量了一下帧率,平均下来是25FPS。ou my god!的确是有点卡。

然后我们知道对于ios来说如果能达到60FPS,那界面绝对不会有卡顿的感觉了。而很少有应用能达到这个水准。那么我们给自己设置了一个目标45FPS。btw,这个目标只是个阶段性目标。

好了下面的过程,就是朝着这个目标前进了。当然我们知道,造成FPS较低的原因,一般都是主线程做了太多的事情,导致帧率降低。这只是个大方向。而对我们来讲,我们需要精准的知道,主线程都做了些什么事情,导致帧率降低。

首先,我们发现的是,读取图片IO的过程发生在了主线程。IO过程一般是比较耗时的,于是我们像把该过程移到了后台线程中处理。发现帧率能够提高到33FPS,这还不够啊。革命尚未完成,同志仍需努力。

之后的过程中,我们把布局预处理,还有圆角,数据预加载之类的事情做上去之后,终于基本达到45。阶段性目标完成。

好了这是一个优化的例子:始于发现问题,止于目标达成。而重要的是其过程,描述问题!!!!

分析问题 (定性or定量)

其实,我一直比较坚信一句话:

当你能够准确的描述一个问题的时候,你到解决问题就没剩几步了。

比如刚才说的卡顿的问题,我们当时是这么描述的:图片读取发生了主线程,主线程中有一部分CPU片段用于文件读取和图片解码,造成主线程阻塞,从而导致帧率下降。当描述到这里的时候,解决方案就比较显而易见了,挪呗。搞到其他线程中之行。把主线程空出来。

而上面的这个描述还只是一个定性的描述分析。只是阐述了现象。虽然能够解决了一个问题,但是对整体问题的贡献有多大,也未可知。所以我们可以当时完全可以这样描述:我们图片缓存在文件系统的平均大小是1MB,其读取时间为10.7ms,图片格式为jpeg,解码一个1M的图片耗时是60ms,也就说当我们要去拿一个图片的时候是70.7ms,当快速滑动的时候,相对于直接从内存中拿图片来说,这个地方占用了大量CPU时间片来处理图片读与解码操作,从而造成了CPU阻塞,造成帧率没有达到60ms。(早期的sdwebimage容易出现此问题,后来都是自己优化其中的IO操作)

当我们使用定量的描述的时候,我们能够比较精确的知道,一个小问题,对于大问题来说到底意味着什么。而定量分析的方案中,当然包含了很多更多的细节信息,尤其是数据信息。这些也正是定量分析的优势所在。BUT,定量分析是一个非常耗时耗力的事情,你要拿到这么多的数据,你势必要付出很多时间,在采集这些数据上面。对于app开发来讲,除非公司给了足够的资源(尤其是时间),你才能像个研究者一样去采集这些数据,一般情况是,大概都会止步到定性分析这一步。其实这也是看具体问题而定了。

不过无论你是使用定性分析的方式还是定量分析的方式。我们的目标是为了找到能够准确表述问题的方式,并且定位问题,以求找到解决方案。而为了达到这个目的一般情况下我们可以使用两种方式:

你的编程功底和对iOS的了解程度都很深,那么完全可以从一些原理性的事情上去分析。我们称之为:逻辑分析法。

或许你的编程功底很深,或许很浅,或许你尝试分析而没有结果。那么可以使用改改代码试试的方法了。我们称之为:实验法。

逻辑分析法, 原理性分析

哈哈,套用马哲的一句话:事物是普遍联系的。既然是普遍联系的,不说必然存在因果,那么通过一定的逻辑分析。是可以找到他们之间的一些蛛丝马迹的关联的。这些关联或许可以解释一些什么。比如刚才卡顿的问题:原理就是主线程CPU被消耗过多,无法及时处理UI任务导致的。这只是一个例子。

我们进行逻辑分析的目的,是为了找到我们的某些代码和问题之间的因果性联系。就是说,我们能够明确知道造成UI卡顿的问题,就是因为IO的问题之类。这个话题说起来,比较深邃了。其中绝大部分实践的方法可以从《数理逻辑》这本书中找到。不过这是本讲数学的书,咱们得稍微换下脑子,把其中的定理,在编程中应用一下。因为我也只是意会了其中的某些东西,讲出来还没有那么功底。就只能麻烦各位自己去琢磨了。:)

实验法,Assume-Action-Response-Test-Assume

我称这个过称为AARTA。这是一个一直往复的过程,在分析的过程中,你得一次次的重复这个过程来找到真正问题的所在。其实,这个方法比较常应用在改BUG这个场景上。其实如果从广义上讲,按照上面咱们对技术优化的定义,改bug也算是一种优化。只不过这个场景比价特殊而已。当无法准确的分析原理,或者当前程序的复杂性过高(低内聚高耦合)已经超出人脑的计算能力范围的时候,那么就可以“猜”了。


(1)假设 assume

根据以往的经验来,设定一个和问题域相关的假设。比如UI卡顿的问题,你怀疑是不是因为图片的问题呢。那么现在就假设是图片的问题!

(2) 尝试进行修改 action

既然假设是图片的问题,那么就把UIImageView从Cell上删掉吧。

(3)看程序的反馈 Response

重新运行一遍程序,看一下程序运行的效果。FPS是否有所改善,而且改善的幅度有多大。

(4)Test

根据,程序的反馈和我们预先设定的目标来判断一下,当前改动是否满足了我们设计的目标。如果有,那么你大概就找到了问题的一个原因。如果没有那么进行下一步。

(5) 重新提出假设 Assume

既然不是图片的问题,那么会不会是其他事情上耗费了CPU呢。比如布局样式的计算。那么重新假设是局部样式的问题。在执行(2)过程。

所谓实验,即是大胆假设,小心取证,如此往复,以求终解。

监控

上面只是进行了一些方法论的探讨。但是有一件事情,是若要优化一定要做的。那就是“监控”。

监控是个非常重要的东西。

监控是个非常重要的东西。

监控是个非常重要的东西。

重要的事情说三遍。尤其是对于运行在生产环境的程序。这就像是一个体检,你得实时掌控程序的运行情况,知道问题出在了哪里,甚至有些时候知道:哎呀,出问题了。没有监控,程序一旦上线之后,就像脱缰的野马,跑到哪里,做了什么,你就是一头忙然了。突然有一天,老板说有人反馈咱们的app经常崩溃,当你没有crash监控,这个你都不知道从哪里查起。

而且,监控也是优化的数据来源。他能够通过数据的指标来非常直观的告诉你,程序哪里有问题,你优化之后,效果是怎样的。现在网上有很多这方面的服务提供出来,比如bugly之类的,甚至有些是APM(application performance manager),直接监控到程序的运行状态和性能。google一下,能搜出不少来。可以酌情,应用在自己开发的app中。

总结

说了半天,总结一下。优化是在可控的范围内有目的性的对现有程序的修改。一般可以使用逻辑分析法和实验法来定位、分析、描述问题。或者定性或者定量。无论哪种,要想优化,你得先建立起对自己app运行的监控体系。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,391评论 25 707
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,169评论 11 349
  • 三、隐藏的大惊喜 我懒得做饭,就在每个房间门口扔了一堆腐肉,一桶牛奶,然后下楼把昨天的日历撕了,1月1号,我的生日...
    碧玫阅读 525评论 2 5
  • SqlMapConfig.xml 讲解 mybatis的全局配置文件,配置内容如下: properties(属性)...
    暗物质阅读 383评论 0 2
  • 三千八百坎 坎坎见真情 古藤缠绕草木年华 泉瀑潺流清幽凉爽 一路追着瀑布的踪迹 探寻着闽赣古道。 ​ ​​​
    当当哟阅读 149评论 0 0