【问题标题】:What is Swift String to NSString bridging overhead?什么是 Swift String 到 NSString 的桥接开销?
【发布时间】:2016-03-26 05:34:57
【问题描述】:

我已经开始学习 Swift。我读到,在使用 Cocoa 类时,Swift String 被桥接到 NSString。此操作的开销是多少?

【问题讨论】:

    标签: string swift performance bridge


    【解决方案1】:

    来自iOS Developer Library

    Swift 自动在 String 类型和 NSString 类之间建立桥梁。

    来自 Swift 源代码 -> stdlib/public/core/String.swift

    StringNSStringString 桥接到Objective-C 起源于 Objective-C 的可能会将其字符存储在一个 NSString。因为NSString 的任意子类都可以 成为String,不保证代表或 在这种情况下效率。由于NSString 是不可变的,所以它是 就好像存储被某个副本共享:第一个是 任何变异操作序列都会导致元素被复制 到独特的、连续的存储中,这可能会花费O(N) 时间和 空格,其中N 是字符串表示的长度(或 更多,如果底层NSString有异常表现 特征)。

    这些是我从那段中得出的结论。注意:NSString 是不可变的,我不确定 NSMutableString 是如何工作的,这可能取决于您的具体情况。

    1. NSString 桥接到String 本质上是免费操作;无需转换。 O(1)
      • NSString 使用 UTF-16 作为后备存储。 String 使用 UTF-16 或 ASCII,因此两个实例可以使用相同的内存。
    2. 但是,如果您随后对 String 结构进行变异,则需要从原始 NSString 复制所有内存。在)
      • String 不能在不修改 NSString 的内存的情况下修改其后备内存。这就是为什么必须复制内存以便String 拥有自己的内存的原因。

    swift 使用的支持StringCore 的源代码。

    【讨论】:

    • 虽然不复制字符串的数据,但是否复制了结构?字符串对象通常分两部分实现,一是动态分配的数组,二是指向数组并封装的结构体/类。我知道前者不是复制的。是后者吗?
    • String 结构本身是被复制的。目前它的大小为 3 个字,因此不是一个昂贵的副本:1 个字用于开头,1 个字用于长度,1 个字用于缓冲区所有者。我认为(但已经验证)memcpy 指令之上的唯一开销是处理缓冲区所有者的任何引用计数。
    • 16 字节的 memcpy(与我们这里的 12 字节相比,尽管它们的速度可能相同)需要 0.7 纳秒,而 Objectvie-C 保留/释放需要 23.3 纳秒。您的里程可能会有所不同,但 tldr 是“难以置信的快”。来源:mikeash.com/pyblog/…
    猜你喜欢
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    相关资源
    最近更新 更多