我正在Swift中移植路径跟踪器(出于娱乐目的)。它使用简单的八叉树加速结构,实现为SpatialIndex
类,并为子节点提供[SpatialIndex?]
属性。我写了一种方法,通过找到任意点的最接近点来测试加速度结构。第一种方法是递归的,并且效果很好。然后,我尝试实现一种基于循环的方法,该方法也可以正常工作,但速度慢了3倍,并且其中大部分时间都花在了保留/释放调用上。
问题是,我不太了解为什么它比递归方法需要更多的保留/释放调用,而且我也不知道如何追踪ARC的实际情况。在这种情况下,引用计数大约占所花费时间的一半。至少可以说,这似乎有点过分。
当我搜索ARC问题时,我通常会发现与保留循环相关的东西。我真正想做的是有效绕过整个系统,因为我知道树的内存布局无法更改。
所以我的问题基本上是:当ARC导致性能问题时,什么是跟踪其实际花费的时间参考计数的最佳选择,以及如何加快速度?
答案 0 :(得分:0)
您可以使用Unmanaged
type绕过特定对象的ARC。我还没有尝试太多,但是我想它看起来像这样:
在性能至关重要的部分之前,将要跳过ARC的对象包装在Unmanaged
值中:
let unmanagedObj = Unmanaged.passRetained(obj)
在关键部分中,传递Unmanaged
值不会带来引用计数开销。当您需要使用该对象时,请像这样提取它:
let obj = unmanagedObj.takeUnretainedValue()
关键部分之后,释放对象:
unmanagedObj.release()
当然,这仅在您控制传递对象所需的功能时才起作用,因为您必须将其从采用对象更改为采用Unmanaged
值。我不知道您是否是这种情况。
也许您可以通过将对象图的不同部分切换到Unmanaged
来找出哪些类型的对象在代码中引起最多的引用计数开销。