通常,水平约束方程和垂直约束方程彼此独立,但长宽比约束链接两个维度,将两个较小的线性方程组合并为一个大组。根据我的理解,两个较小的集合应该比组合的大集合更容易解决,因此,我预期宽高比限制会降低性能。但是,在每个维度中具有100个约束视图的简单测试显示性能没有差异。为什么呢?
在自动布局中,每个布局约束都是一个线性方程式:
view2.attribute = multiplier * view1.attribute + constant
当所有约束的集合只有一个解决方案时,给出了非模糊和非冲突的布局。
在方法layoutSubviews()
内,系统解析约束,即它计算来自这些约束的所有子视图的帧。任务是解决线性方程组,可以通过应用Gauss algorithm来完成。
现在只要不涉及宽高比限制水平和垂直尺寸彼此独立。因此,水平约束有一组 h 线性方程,一组 v 线性方程为垂直约束。这些可以单独解决。
但是,向视图添加宽高比约束会链接两个维度。系统必须解决一组较大的 h + v 线性方程组,而不是两组独立的线性方程组。
由于求解 n 线性方程组的复杂性介于O(n 2 )和O(n 之间3 ),根据算法,使用 h 和 v 来解决两个系统必须更快方程比一个系统 h + v 方程。因此,我希望只要存在至少一个宽高比约束,解决约束的过程(即layoutSubviews()
方法)就会显着延长。
为了解决这个问题,我创建了一个空的示例项目,沿水平方向添加了100个视图,沿垂直轴添加了100个视图并正确约束它们。然后我测量了布局过程的时间:
override func layoutSubviews() {
let t1 = mach_absolute_time()
super.layoutSubviews()
let t2 = mach_absolute_time()
print(t2 - t1)
}
然后我用纵横比约束替换其中一个垂直约束并再次测量时间。 结果几乎相同。这是我不理解的部分。
以下是我创建和约束的视图的设置。为了获得更好的可见性,屏幕截图仅显示每个方向的20个视图,而不是我测量时间的100个视图。
答案 0 :(得分:1)
我不知道实施细节但你的逻辑论证似乎是公平的。
您描述的简单测试过于基本无法区分,计算机/处理器如此快速地进行计算,对于像100这样的小样本大小,查看完成时间,或者说完成之间的差异时间很少。
您的测试应该真正使用数千或数十万个视图。
此外,计算机/处理器一直在做很多不同的事情,它们是并行处理。有时这是在多个核心上,但每个核心同时也会做多个不同的事情。这会影响您的结果,因为您不知道在计时时发生了什么。
您的测试应该真正运行数千或数十万次。
所以,如果你增加了复杂性'对于测试,以及要求解的方程的数量,你应该开始看到解决这些方程的相对成本的差异。
答案 1 :(得分:1)
添加宽高比约束并不一定会使方程组相互依赖,使用约束描述 x 位置和宽度的等式可以计算出顶行中所有视图的位置而无需首先求解垂直方程或连接方程,一旦引擎求解第一组方程,它只需求解 y 方程常数而不是方程组,同样适用于垂直列视图。
解决这个方程的引擎(我猜)具有可以根据之前的结论提高性能的启发式方法,而且我认为还有更多。
我认为你可以强制解决只能通过求解方程组来解决的情况,但我担心Interface Builder会出现约束错误,但我现在想不到这种情况。