childNodeWithName在SpriteKit中的表现如何?
What is the performance of childNodeWithName in SpriteKit?
在SpriteKit中,SKNode的方法childNodeWithName:
在接收节点的children中搜索具有特定名称的节点。我知道。
但是性能呢?我的意思是,它是如何实现的?
这个问题的可能答案是:
- 它的计算复杂度为 O(n),因为它确实遍历了所有 children
- 它的计算复杂度为 O(log n) 因为它确实使用了一些索引结构
我问的原因
如果用for循环实现,那么复杂度为O(n)(n为当前节点children的个数)。那么我们应该避免在一些关键点调用它,比如GameScene的update方法。至少当有很多 children.
在优化我的 iOS 游戏几个小时后,我相信 childNodeWithName:
的 运行 时间是线性的而不是对数的。
我遇到的情况是:
场景中有 500 个节点,每个节点都有一个唯一的名称(4 个字节的 UUID,我知道这不是最佳做法)。每 100 毫秒我为每个节点调用 childNodeWithName
以从服务器端应用更新。然后,很明显我观察到 fps 意外下降,即使没有来自服务器的更新(这意味着只有 childNodeWithName
被调用并且 return 立即被调用)。
所以我决定用自定义 Set<String>
替换 childNodeWithName
只是为了检查 SKNode 是否包含具有特定名称的节点。它奏效了,fps 下降消失了。
作为半答案,Apple 强烈建议我们 缓存 childNodeWithName
或 enumerateChildNodesWithName
调用的结果。
参见:
WWDC 2014 - 第 608 节 - 构建 Sprite Kit 游戏的最佳实践,16 分钟大关
含义很明确:无论查找速度有多快table,如果您有经常引用的对象,那么您应该保留对它们的引用。 (尤其是在 60fps 时。)
至于查找机制,这些集合 containers/clusters 是高度优化的,并根据多种因素使用不同的算法。所以我们不能假设 NSDictionary、NSArray、NSSet 或它们的 Swift 变体实际上可以作为散列 tables 或其他任何东西工作。并且,除非另有标记,否则不能假定具有特定的 O(*) 特性。
(Google 对 NS[Collection] 底层实现细节的精彩分析。)
例如http://ciechanowski.me/blog/2014/03/05/exposing-nsmutablearray/
在SpriteKit中,SKNode的方法childNodeWithName:
在接收节点的children中搜索具有特定名称的节点。我知道。
但是性能呢?我的意思是,它是如何实现的?
这个问题的可能答案是:
- 它的计算复杂度为 O(n),因为它确实遍历了所有 children
- 它的计算复杂度为 O(log n) 因为它确实使用了一些索引结构
我问的原因
如果用for循环实现,那么复杂度为O(n)(n为当前节点children的个数)。那么我们应该避免在一些关键点调用它,比如GameScene的update方法。至少当有很多 children.
在优化我的 iOS 游戏几个小时后,我相信 childNodeWithName:
的 运行 时间是线性的而不是对数的。
我遇到的情况是:
场景中有 500 个节点,每个节点都有一个唯一的名称(4 个字节的 UUID,我知道这不是最佳做法)。每 100 毫秒我为每个节点调用 childNodeWithName
以从服务器端应用更新。然后,很明显我观察到 fps 意外下降,即使没有来自服务器的更新(这意味着只有 childNodeWithName
被调用并且 return 立即被调用)。
所以我决定用自定义 Set<String>
替换 childNodeWithName
只是为了检查 SKNode 是否包含具有特定名称的节点。它奏效了,fps 下降消失了。
作为半答案,Apple 强烈建议我们 缓存 childNodeWithName
或 enumerateChildNodesWithName
调用的结果。
参见:
WWDC 2014 - 第 608 节 - 构建 Sprite Kit 游戏的最佳实践,16 分钟大关
含义很明确:无论查找速度有多快table,如果您有经常引用的对象,那么您应该保留对它们的引用。 (尤其是在 60fps 时。)
至于查找机制,这些集合 containers/clusters 是高度优化的,并根据多种因素使用不同的算法。所以我们不能假设 NSDictionary、NSArray、NSSet 或它们的 Swift 变体实际上可以作为散列 tables 或其他任何东西工作。并且,除非另有标记,否则不能假定具有特定的 O(*) 特性。
(Google 对 NS[Collection] 底层实现细节的精彩分析。)
例如http://ciechanowski.me/blog/2014/03/05/exposing-nsmutablearray/