Swift 的演员阵容的运行时成本是多少?

Posted

技术标签:

【中文标题】Swift 的演员阵容的运行时成本是多少?【英文标题】:What is the runtime cost of Swift's casts? 【发布时间】:2015-04-20 14:18:09 【问题描述】:

以下类型转换会产生哪些不同的运行时成本?

    常量的数字转换,例如:

    let f = 0.1 as CGFloat
    

    我想这具有零运行时成本。

    运行时值的数字转换,例如:

    let f = someDoubleValue as CGFloat
    

    我想这具有极小的运行时成本。

    Upcast,例如:

    let dict: [String: Int] = ...
    let anyObj = dict as AnyObject
    

    我希望它的运行时成本为零。

    可失败的向下转型,例如:

    let anyObj: AnyObject = ...
    if let str = anyObj as? String  ... 
    

    我希望它的运行时成本与 anyObj 的动态类型的层次结构中的类数量成正比。

    强制向下转换,例如:

    let anyObj: AnyObject = ...
    let str = anyObj as! String
    

    也许强制下垂的成本略低?

    强制向下转换集合,例如:

    let dates: [AnyObject] = ...
    for date in dates as! [NSDate]  ... 
    

    这里会发生什么——尤其是当dates 来自NSArray 时?此演员表的运行时成本是否与其元素的数量成正比?如果我转换为像 [String: [String: [Int]]] 这样更复杂的集合类型会怎样——是否遍历整个集合以确保其所有元素和子元素都符合这个转换?

对于前四种情况,我的断言是否正确?

【问题讨论】:

我猜你的许多问题有太多可能和正确的答案。例如。你的号码2:优化器可以检测f 的使用方式,如果机器架构适合,它可以直接使用someDoubleValue 作为Double,而在其他情况下,它必须将值复制到一些额外的内存中。万一它需要内存,因为它可能会将所有内存都保存在寄存器中。如果在这种情况下的性能存在问题:创建一个基准。 据我了解,#3 并不是真正向上转换的示例,因为 swift 字典是一个结构,当您将其“转换”为 AnyObject 时,swift 实际上会创建 NSDictionary。这对于 Int -> NSNumber、String -> NSString 和其他必须相同 【参考方案1】:

如果明显可转换(如数字转换和向上转换),则为 O(1)(几乎为 0):案例 1、2、3。

对于其他非收藏的铸件,显然是O(1): case 4, 5。

对于集合向下转换:

as? 是 O(n),因为元素类型检查是急切地执行的。 本机强制向下转换为 O(1),因为元素类型检查被推迟:案例 6。 桥接强制向下转换 (NSArray as! [NSDate]) 是 O(n),因为急切地执行元素类型检查。 嵌套集合是递归转换的,因此您只需递归应用上述规则。

来源:

    https://github.com/apple/swift/blob/master/stdlib/public/runtime/Casting.cpp https://github.com/apple/swift/blob/master/stdlib/public/core/ArrayCast.swift https://github.com/apple/swift/blob/master/stdlib/public/core/HashedCollections.swift.gyb

【讨论】:

很好的答案,感谢您彻底调查。【参考方案2】:

只是想补充一点,协议类型转换的运行时成本是可怕的。我试图在反汇编视图中查看它,只是忘记了正在发生的事情。所以像这样的一行:

(self as! SomeProtocol).someMethod()

导致保留/释放(涉及内存障碍),然后调用旧好的 objc_msgSend()(!)但与 someMethod() 无关,我猜是因为 selfSomeProtocol 之一是派生自class,然后是一个非常长的函数调用链,其中涉及一些循环。就像我说的那样,我失去了在反汇编视图中调试这一行代码的耐心。

虽然协议是一个非常好的抽象,但在性能关键代码中应谨慎使用。

【讨论】:

以上是关于Swift 的演员阵容的运行时成本是多少?的主要内容,如果未能解决你的问题,请参考以下文章

在 Akka 中创建演员的成本是多少?

Swift 捕获运行时异常

Swift 3.0 运行时获取类属性

ASP.NET 在运行时动态生成引导面板

指定的演员表无效(xamarin 形式)

仅在运行时知道类型时的 Swift 4 JSON 解码