Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift&x27的运行成本是多少;演员?_Swift_Casting_Time Complexity_Overhead - Fatal编程技术网

Swift&x27的运行成本是多少;演员?

Swift&x27的运行成本是多少;演员?,swift,casting,time-complexity,overhead,Swift,Casting,Time Complexity,Overhead,以下类型转换产生的不同运行时成本是什么 常数的数值转换,例如: let f = 0.1 as CGFloat let f = someDoubleValue as CGFloat let dict: [String: Int] = ... let anyObj = dict as AnyObject let anyObj: AnyObject = ... if let str = anyObj as? String { ... } let anyObj: AnyObject = ...

以下类型转换产生的不同运行时成本是什么

  • 常数的数值转换,例如:

    let f = 0.1 as CGFloat
    
    let f = someDoubleValue as CGFloat
    
    let dict: [String: Int] = ...
    let anyObj = dict as AnyObject
    
    let anyObj: AnyObject = ...
    if let str = anyObj as? String { ... }
    
    let anyObj: AnyObject = ...
    let str = anyObj as! String
    
    let dates: [AnyObject] = ...
    for date in dates as! [NSDate] { ... }
    
    我可以想象它的运行时成本为零

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

    let f = 0.1 as CGFloat
    
    let f = someDoubleValue as CGFloat
    
    let dict: [String: Int] = ...
    let anyObj = dict as AnyObject
    
    let anyObj: AnyObject = ...
    if let str = anyObj as? String { ... }
    
    let anyObj: AnyObject = ...
    let str = anyObj as! String
    
    let dates: [AnyObject] = ...
    for date in dates as! [NSDate] { ... }
    
    我可以想象这有一个非常小的运行时成本

  • 向上投射,例如:

    let f = 0.1 as CGFloat
    
    let f = someDoubleValue as CGFloat
    
    let dict: [String: Int] = ...
    let anyObj = dict as AnyObject
    
    let anyObj: AnyObject = ...
    if let str = anyObj as? String { ... }
    
    let anyObj: AnyObject = ...
    let str = anyObj as! String
    
    let dates: [AnyObject] = ...
    for date in dates as! [NSDate] { ... }
    
    我希望它的运行时成本为零

  • 可故障向下广播,例如:

    let f = 0.1 as CGFloat
    
    let f = someDoubleValue as CGFloat
    
    let dict: [String: Int] = ...
    let anyObj = dict as AnyObject
    
    let anyObj: AnyObject = ...
    if let str = anyObj as? String { ... }
    
    let anyObj: AnyObject = ...
    let str = anyObj as! String
    
    let dates: [AnyObject] = ...
    for date in dates as! [NSDate] { ... }
    
    我希望它的运行时成本与
    anyObj
    动态类型层次结构中的类数量成比例

  • 强制下压,例如:

    let f = 0.1 as CGFloat
    
    let f = someDoubleValue as CGFloat
    
    let dict: [String: Int] = ...
    let anyObj = dict as AnyObject
    
    let anyObj: AnyObject = ...
    if let str = anyObj as? String { ... }
    
    let anyObj: AnyObject = ...
    let str = anyObj as! String
    
    let dates: [AnyObject] = ...
    for date in dates as! [NSDate] { ... }
    
    也许强制向下倾斜的成本稍微低一点

  • 强制向下播放收藏,例如:

    let f = 0.1 as CGFloat
    
    let f = someDoubleValue as CGFloat
    
    let dict: [String: Int] = ...
    let anyObj = dict as AnyObject
    
    let anyObj: AnyObject = ...
    if let str = anyObj as? String { ... }
    
    let anyObj: AnyObject = ...
    let str = anyObj as! String
    
    let dates: [AnyObject] = ...
    for date in dates as! [NSDate] { ... }
    
    这里发生了什么-尤其是当
    日期
    来自
    NSArray
    时?此强制转换的运行时成本与其元素数成正比吗?如果我强制转换为更复杂的集合类型,如
    [String:[String:[Int]]]]
    ——是否遍历整个集合以确保其所有元素和子元素都符合此强制转换

  • 对于前四种情况中的每一种,我的断言都是正确的吗?

    • 如果它明显是可浇铸的(如数字浇铸和向上浇铸),则为O(1)(几乎为0):情况1、2、3

    • 对于其他非收集铸件,显然是O(1):情况4,5

    • 对于收集下铸件:

      • as?
        是O(n),因为需要执行元素类型检查
      • 本机强制向下转换为O(1),因为元素类型检查延迟:情况6
      • 桥接强制下推(
        NSArray as![NSDate]
        )为O(n),因为迫切需要执行元素类型检查
      • 嵌套集合是递归铸造的,因此您只需递归地应用上述规则
    资料来源:


  • 只是想补充一点,协议类型转换的运行时成本是可怕的。我试着在反汇编视图中查看它,只是不知道发生了什么。这样一句话:

    (self as! SomeProtocol).someMethod()
    
    结果在保留/释放(涉及记忆障碍)中,然后调用旧的good
    objc_msgSend()
    (!)但与
    someMethod()
    无关,我猜想是因为
    self
    SomeProtocol
    中的一个派生自
    类,然后是一个非常长的函数调用链,其中包含一些循环。就像我说的,我在反汇编视图中调试这一行代码时失去了耐心


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

    我想对于您的许多问题,可能的正确答案太多了。例如,您的第二个问题:优化器可以检测如何使用
    f
    ,如果机器架构适合,它可以直接使用
    someDoubleValue
    作为
    Double
    ,而在其他情况下,它必须将值复制到一些额外的内存中。在这种情况下,它将需要内存,因为它可能会保持在寄存器中的所有。如果这种情况下的性能有问题:创建一个基准。据我所知,#3并不是真正的向上转换示例,因为swift dictionary是一个结构,当您将其“转换”到任何对象时,swift实际上创建了NSDictionary。对于Int->NSNumber,String->NSString和其他伟大的答案,这必须是相同的,感谢您仔细研究这一点。