将给定编码中的字节序列附加到CFMutableString

时间:2013-03-21 20:33:29

标签: objective-c macos

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

我最有效的方法是:

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

有没有更好的方法呢?

1 个答案:

答案 0 :(得分:0)

我假设你实际上在询问效率(如CPU时间),并且你确实在你的字符串构建中遇到了瓶颈。我会以降低可能性的顺序抛出一些想法。

通常,您会将一堆内容添加到一个大字符串中,并且可以使用CFStringCreateByCombiningStrings / -[NSArray componentsJoinedByString:]将时间缩短20-50%。

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跳过临时字符串。

同样可能,尽管不是那么可能,其他一些像iconvicu这样的Unicode库可以以足够大的余量击败CF值得。如果是这样,请先将所有内容转换为右端UTF-16,然后CFStringCreateWithCharacters(如果使用数组连接)或CFStringAppendCharacters(如果不是)。

然后总是有分配器和引用计数的技巧。如果你为字符串和数组存储创建了一个区域分配器,并且创建了一个无用的CFArrayCallbacks,你只需要几个malloc调用即可构建所有内容,几乎不需要引用计数,只需将所有内容放在区域的地板上,然后释放它们一次你做componentsJoinedByString:(当然,它使用默认的分配器)。

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