Optimising Autolayout

本文翻译自Martin Pilkington的文章Optimising Autolayout,也是本人翻译的第一篇技术文章。Florian Kugler在最近发表了一篇文章Autolayout Performance on iOS。这篇文章是关于Autolayout在添加视图所使用的时间,以及随着视图数量的增加,其所用时间的增长规律。这篇文章为我们提供了很多有用的信息,但是并没有很好的反应出Autolayout的真实性能,反而展示了一系列最差的情况。在这篇文章中,我将会更多的关注为什么Florian会得到这样的结果。我希望指出一些程序员可能会犯的、关于Autolayout的一些不好的习惯;并且关注Autolayout会花费数秒来布局几百个视图Autolayout可以快速地布局好几百个视图这两个看似截然相反的观点都正确的原因。##方法首先,我先阐明我是怎么样来处理上述的这些数字的。在我认为,这种方法与Florian的测量方式稍有不同,但是在展示布局方面却非常的相似。我在原来的程序基础上做了一些变动。你可以从我的GitHub上找到本文的项目。##原景再现因为我的这些方法以及使用的设备与Florian的有些不同,所用开始我会做一些与他一样的事情。他的项目测试了布局的三种形式:- 扁平视图的层次结构,全部视图布局在一个共同的根视图上- 扁平视图的层次结构,每个视图都相互约束着- 嵌套视图的层次结构,每个视图都相互约束着另外,Florian也做了只是上述两种层次结构下只是简单设置视图的frame的方式。下面的图表展示了我从扁平结构下得到的结果:

扁平式结构布局
若与Florian得到的结果比较,你会发现这两个结果截然不同。在Florian得到的图表中,绿线比橙线所表示的性能要差,但是几乎是差不多的;而在我得到的图表中,橙线的性能效果却更差(比如视图数量为600个时,尽管我的设备性能比Florian的更好,但是Florian只花费了5秒,而我的却接近于7.5秒。),但是绿线所表现的性能却比Florain的要好很多(比如同样在视图数量为600时,我得到的时间差不多为2.5秒,Florian得到的时间在6-7秒左右)。我认为造成这种不同的主要原因是因为测量的不同。在前面我提到,我测量的依据是方法方法创建约束的时间。为了做到这一点,我会在每个方法的最后在根视图上主动激活-layoutIfNeeded方法。这就迫使Autolayout马上执行,而不是延后到当前runloop结束的时候——这就意味着Instrument计算的是创建约束的方法(method creating the constraints)的性能,而不是系统方法(system method)的系能。我认为Florian当时测量的是CPU的整个工作时间,但是这并不一定都是由于Autolayout所引起的。我认为我的方法更能表现Autolayout的行为,但是Florian的方法则更好的表现出来整个程序可能卡顿的时长。无论如何,但是真是的数据并不会像曲线这样夸张,以及任何我们可以找到的相关的提高性能的方法。
嵌套式结构布局
嵌套式结构的布局结果与Florian的结构几乎相同。曲线的吻合度几乎相同,唯一的不同就是我的运行结构稍微的快一点点,这与我运行在运行速度更快的设备上相关。##局部(小范围)的力量(The Power Of Locality)我在源代码中发现的其中一个内容就是,在源代码中,所有的约束都是加载同一个根视图上的。在某些场合下,约束与根视图相关,这种形式是必须的。与一个约束相关的所有视图必须在被加视图(即父视图)的视图子树(Subtree of the view)上。在这种情况下,你可以把所有的约束都添加到程序的根视图上。虽然你有很多原因不想这么做。很明显,把约束加在较小范围内会更容易理解。另一个原因就是,这种方法对于性能有很显著的影响。来看看我们的扁平式布局。当视图需要被约束在根视图上时(位置约束),它的尺寸约束却没有。我修改了代码,让视图的尺寸约束添加到其子视图上,并得到如下的结果:
扁平式布局
为了得到实际的数量,200个视图都加到根视图上时,布局花费了22.75秒,而把约束添加到最近的父视图时,布局却仅仅花了2秒钟。把相同的约束添加到根视图上会导致代码的运行速度慢11倍。结果很明确:使用Autolayout布局时,尽可能地将所有约束都加在较小的范围内(locally)。##修改已存在的视图层级结构Florian在他的文章中提到,约束的满足问题设计到一个多元复杂度(polynomial complexity),我们也可以从上述图表的曲线中看出。但是,上面的测试根本不能代表现实中我们对Autolayout的使用。如果知道Autolayout在添加1000个视图到父视图有多快,这是非常有用的,就好比你知道NSArray添加数百万个对象有多快 一样。但是,大部分的NSArray很少有持有超过数百个内容的,很多持有的内容都少于十个。同样的,很少有单个视图持有超过40-50个子视图的,或者单个视图有一个视图层级达到20-30层视图这么深的(我认为这些数值基本上也是不可能达到的)。更符合实际情况的是,存在一个视图层,我们希望对一些视图做位移操作,或者是添加一些新的视图。基于此,我做了一些其他的测试。使用与之前一样尺寸的视图,并同样采用扁平式布局和嵌套式布局,然后计算出移动所有的视图以及添加10个新的视图所花费的时间。我们可以从下面的图表中可以看出,即便扁平式结构下,视图的数量达到了1000个,再添加10个视图,其位置布局所消耗的时间也基本是线性的。这是因为我只以根视图为参考,因此,其他视图并不需要重新进行计算。如果我们在一个位置相互约束的视图链中间插入一个视图,就有可能没有这么快了。同样,移动视图布局所消耗的时间也基本是线性的,不过,在视图数量达到1000个时,布局消耗的时间也的确是突然地增加了。同样,这是因为对于一个视图的约束并不依赖与其他任何的兄弟视图。

扁平式

再来看看看嵌套式结构,我们可以发现移动视图所消耗的时间也几乎是线性的。但是其线性的变化却比扁平式结构的更平缓,但是这正是这个图表的一个欺骗性的外表,他们其实基本上是一样的。当添加视图时,我们确实看到了一条曲线,但此时,我们是在添加一组是个视图的布局层结构,每个布局都与前一个相互约束着。
嵌套式

本文需要表达的事是与之前的测试相比,布局消耗的时间能有多快。添加1000个位置视图消耗了6.6秒,但是再添加10个视图却只消耗了0.055秒。这都归功于Cassowary Constraint Solver。这是一个递增的系统,不用每次都重头开始重新解决整个问题。它可以重复使用之前计算好的一切,当你做添加、编辑或移除约束时,仅仅只需要调整下结果即可。这就是为什么它会消耗数秒钟时间来一次性添加几百个视图的原因,但是你可以在这之后快速地重新调整窗口的尺寸,重新计算所有的约束和frame集合。Autolayout比手动设置视图的frame要慢一些。如果有特定的算法专门用于单个视图,将会执行的更快。Autolayout的优势并不在于在运行时使布局实现的更加快速,而是为了让我们在代码中能够更快速和方便的定义布局。与其他许多工具一样,Autolayout得益于现在设备强大的处理能力,使我们能够更轻松地来写App。在大多数情况下,如果使用得当,Autolayout将会非常快速的实现需求。这听起来可能会像是在狡辩,但这与我们使用更高级的编程语言而不是集成语言是一样的道理啊。

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

推荐阅读更多精彩内容