0

我有一个 CFMutableString 对象,我想在给定编码(UTF-8、UTF-16、UTF-16LE、UTF-16BE 等)中附加一个字节序列

我拥有的最有效的方法是:

CFStringRef tmp = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, numBytes, encoding, NO, kCFAllocatorNull);
CFStringAppend(myMutableString, tmp);
CFRelease(tmp);

有没有更好的方法呢?

4

1 回答 1

0

我假设您实际上是在询问效率(如 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 库喜欢iconvicu可以以足够大的优势击败 CF,这是值得的。如果是这样,首先将所有内容都转换为右端 UTF-16,然后CFStringCreateWithCharacters(如果使用数组连接)或CFStringAppendCharacters(如果不是)。

然后总是有分配器和引用计数的技巧。如果你为字符串和数组存储创建一个区域分配器,以及一个不做任何事情的 CFArrayCallbacks,你可以只用几个 malloc 调用和几乎没有引用计数来构建所有东西,只需将所有东西放在区域的地板上,然后释放它们一次你这样做componentsJoinedByString:(当然,它使用默认分配器)。

当然,有了一些额外的应用知识,各种事情都是可能的。举一个非常明显的例子,假设您要附加一堆字符串,这些字符串都是 16 字节值的十六进制编码。在这种情况下,只需分配一大块 32*n+1 unichar,通过复制(右端 UTF-16)、从指针偏移 1 个字节(错误端 UTF-16)复制来“解码”您的 UTF,或用 0 交替字节(UTF-8),然后做一个大CFStringCreateWithCharactersNoCopy的 .

于 2013-03-22T01:14:29.757 回答