我假设您实际上是在询问效率(如 CPU 时间),并且您实际上确实在构建字符串时遇到了瓶颈。我将按照有用的可能性降序提出一些想法。
通常你将一堆东西附加到一个大字符串中,你可以使用CFStringCreateByCombiningStrings
/将时间缩短 20-50% -[NSArray componentsJoinedByString:]
。
CFStringRef tmp = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, numBytes, encoding, NO, kCFAllocatorNull);
CFStringAppend(myMutableString, tmp);
CFRelease(tmp);
…做这个:
CFStringRef tmp = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, numBytes, encoding, NO, kCFAllocatorNull);
CFArrayAppendValue(myMutableArray, tmp);
CFRelease(tmp);
// ... after you've finished accumulating everything
CFString *myString = CFStringCreateByCombiningStrings(kCFAllocatorDefault, myMutableArray, kEmptyString);
有时您知道最终要得到的字符串的大小,并且可以通过在对CFStringCreateMutable
/ 的初始调用中使用正确的容量来缩短时间-[NSMutableString stringWithCapacity:]
。当然,这种优化与数组连接不兼容。
您可以避免一些转换成本,如果您不使用数组连接,则可以避免一些临时CFString
创建成本。
显然,右端 UTF-16 与CFString
“字符”是一样的,所以你可以使用CFStringCreateWithCharactersNoCopy
. 或CFStringAppendCharacters
。
对于错误字节序的 UTF-16,“NoCopy”没有帮助,甚至可能有点伤害。此外,您可以比仅通过字节交换转换为右端 UTF-16 的通用转换更快地执行某些操作,特别是如果您可以就地执行此操作。我不会认为这会更快(尤其是在大字符串上),但如果这确实是一个瓶颈,那么绝对值得尝试和计时。
将指针移动 2 个字节后,以 BOM 为前缀的 UTF-16 就是其中之一。
对于 UTF-8,“NoCopy”同样没有帮助,而且可能会受到一点伤害。但是您显然确实需要进行转换。虽然您可能能够找到/编写比 CF 更快的解码器,但它似乎比使用错误字节序的 UTF-16 的可能性要小得多。但是您仍然可以使用 跳过临时字符串CFStringAppendCString
。
也有可能,尽管不太可能,其他一些 Unicode 库喜欢iconv
或icu
可以以足够大的优势击败 CF,这是值得的。如果是这样,首先将所有内容都转换为右端 UTF-16,然后CFStringCreateWithCharacters
(如果使用数组连接)或CFStringAppendCharacters
(如果不是)。
然后总是有分配器和引用计数的技巧。如果你为字符串和数组存储创建一个区域分配器,以及一个不做任何事情的 CFArrayCallbacks,你可以只用几个 malloc 调用和几乎没有引用计数来构建所有东西,只需将所有东西放在区域的地板上,然后释放它们一次你这样做componentsJoinedByString:
(当然,它使用默认分配器)。
当然,有了一些额外的应用知识,各种事情都是可能的。举一个非常明显的例子,假设您要附加一堆字符串,这些字符串都是 16 字节值的十六进制编码。在这种情况下,只需分配一大块 32*n+1 unichar
,通过复制(右端 UTF-16)、从指针偏移 1 个字节(错误端 UTF-16)复制来“解码”您的 UTF,或用 0 交替字节(UTF-8),然后做一个大CFStringCreateWithCharactersNoCopy
的 .