我有一个CFMutableString对象,我想在给定的编码中附加一个字节序列(UTF-8,UTF-16,UTF-16LE,UTF-16BE等)
我最有效的方法是:
CFStringRef tmp = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, numBytes, encoding, NO, kCFAllocatorNull);
CFStringAppend(myMutableString, tmp);
CFRelease(tmp);
有没有更好的方法呢?
答案 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
跳过临时字符串。
同样可能,尽管不是那么可能,其他一些像iconv
或icu
这样的Unicode库可以以足够大的余量击败CF值得。如果是这样,请先将所有内容转换为右端UTF-16,然后CFStringCreateWithCharacters
(如果使用数组连接)或CFStringAppendCharacters
(如果不是)。
然后总是有分配器和引用计数的技巧。如果你为字符串和数组存储创建了一个区域分配器,并且创建了一个无用的CFArrayCallbacks,你只需要几个malloc调用即可构建所有内容,几乎不需要引用计数,只需将所有内容放在区域的地板上,然后释放它们一次你做componentsJoinedByString:
(当然,它使用默认的分配器)。
当然,除了一些额外的应用知识外,各种各样的事情都是可能的。举一个非常明显的情况,假设您附加了一串字符串,这些字符串都是16字节值的十六进制编码。在这种情况下,只需分配一个32 * n + 1 unichar
的大块,通过复制(右端UTF-16)“解码”您的UTF,从指针偏移1个字节进行复制(错误的结尾) UTF-16),或带0的交替字节(UTF-8),然后做一个大的CFStringCreateWithCharactersNoCopy
。