tl;博士:
通常,水平约束方程和垂直约束方程是彼此独立的,但长宽比约束将两个维度联系起来,将两组较小的线性方程合并为一个大组。根据我的理解,两个较小的集合应该比组合的大集合更容易解决,因此,我预计长宽比限制会降低性能。然而,在每个维度上使用 100 个约束 View 进行的简单测试显示性能没有差异。为什么?
<小时/>问题详细信息:
约束是线性方程
在自动布局中,每个布局约束都是一个线性方程:
view2.attribute = multiplier * view1.attribute + constant
当所有约束的集合恰好有一个解决方案时,给出明确且不冲突的布局。
在方法 layoutSubviews()
中,系统解决约束,即根据这些约束计算所有 subview 的框架。任务是求解线性方程组,可以通过应用 Gauss algorithm 来完成.
x 和 y:两组独立的方程组
现在只要不涉及宽高比限制水平和垂直尺寸是相互独立的。因此,对于水平约束有一组 h 线性方程,对于水平约束有一组 v 线性方程垂直限制。这些可以单独解决。
但是,向 View 添加宽高比约束会链接两个维度。系统必须求解一组更大的 h + v 线性方程,而不是两组独立的线性方程。
求解线性方程组的复杂性
由于求解 n 个线性方程组的复杂度介于 O(n2) 和 O(n 3),根据算法的不同,用 h 和 v 求解两个系统一定会更快强> 方程比具有 h + v 方程的系统更好。因此,我预计只要存在至少一个宽高比约束,解决约束的过程(即 layoutSubviews()
方法)就会明显花费更长的时间。
为了解决这个问题,我创建了一个空的示例项目,沿水平轴添加了 100 个 View ,沿垂直轴添加了 100 个 View ,并正确约束了它们。然后我测量了布局过程的时间:
override func layoutSubviews() {
let t1 = mach_absolute_time()
super.layoutSubviews()
let t2 = mach_absolute_time()
print(t2 - t1)
}
然后,我用纵横比约束替换了其中一个垂直约束,并再次测量了时间。 结果几乎是一样的。这是我不明白的部分。
为什么宽高比限制不会对布局性能产生不良影响?
这是我创建和约束的 View 的设置。为了获得更好的可视性,屏幕截图仅显示每个方向的 20 个 View ,而不是我测量时间的 100 个 View 。
最佳答案
我不知道实现细节,但你的逻辑论证似乎很公平。
您描述的简单测试太基础了,无法区分差异,计算机/处理器进行计算的速度非常快,对于像 100 个 View 这样的小样本量,完成时间,或者更确切地说是完成之间的差异次数最少。
您的测试实际上应该使用数千或数十万的 View 。
此外,计算机/处理器一直在做很多不同的事情,它们是并行处理。有时这是在多个核心上进行的,但每个核心也“同时”执行多个不同的操作。这会影响您的结果,因为您不知道计时时发生了什么。
您的测试确实应该运行数千或数十万次。
因此,如果您增加测试的“复杂性”以及要求解的方程的数量,那么您应该开始看到求解这些方程的相对成本的差异。
关于ios - 宽高比限制会降低性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38076059/