Яно ответ правильный.К сожалению, это создает много ненужных временных объектов.Вот гораздо более быстрая (более сложная) реализация, которая в основном делает то же самое, но использует буферы memcpy и unichar, чтобы свести к минимуму распределение памяти.
- (NSString *)reversedString
{
NSUInteger length = [self length];
if (length < 2) {
return self;
}
unichar *characters = calloc(length, sizeof(unichar));
unichar *reversedCharacters = calloc(length, sizeof(unichar));
if (!characters || !reversedCharacters) {
free(characters);
free(reversedCharacters);
return nil;
}
[self getCharacters:characters range:NSMakeRange(0, length)];
NSUInteger i = length - 1;
NSUInteger copiedCharacterCount = 0;
// Starting from the end of self, copy each composed character sequence into reversedCharacters
while (copiedCharacterCount < length) {
NSRange characterRange = [self rangeOfComposedCharacterSequenceAtIndex:i];
memcpy(reversedCharacters + copiedCharacterCount, characters + characterRange.location, characterRange.length * sizeof(unichar));
i = characterRange.location - 1;
copiedCharacterCount += characterRange.length;
}
free(characters);
NSString *reversedString = [[NSString alloc] initWithCharactersNoCopy:reversedCharacters length:length freeWhenDone:YES];
if (!reversedString) {
free(reversedCharacters);
}
return reversedString;
}
Я тестировал это на 100 000 случайных многобайтовых Unicodeстроки длиной от 1 до 128. Эта версия примерно в 4–5 раз быстрее, чем у jano.
Enumerate substrings: 2.890528
MemCopy: 0.671090
Enumerate substrings: 2.840411
MemCopy: 0.662882
Код теста: https://gist.github.com/prachigauriar/9739805.
Обновление : Iпопробуем это снова, просто конвертировав в буфер UTF-32 и изменив его.
- (NSString *)qlc_reversedStringWithUTF32Buffer
{
NSUInteger length = [self length];
if (length < 2) {
return self;
}
NSStringEncoding encoding = NSHostByteOrder() == NS_BigEndian ? NSUTF32BigEndianStringEncoding : NSUTF32LittleEndianStringEncoding;
NSUInteger utf32ByteCount = [self lengthOfBytesUsingEncoding:encoding];
uint32_t *characters = malloc(utf32ByteCount);
if (!characters) {
return nil;
}
[self getBytes:characters maxLength:utf32ByteCount usedLength:NULL encoding:encoding options:0 range:NSMakeRange(0, length) remainingRange:NULL];
NSUInteger utf32Length = utf32ByteCount / sizeof(uint32_t);
NSUInteger halfwayPoint = utf32Length / 2;
for (NSUInteger i = 0; i < halfwayPoint; ++i) {
uint32_t character = characters[utf32Length - i - 1];
characters[utf32Length - i - 1] = characters[i];
characters[i] = character;
}
return [[NSString alloc] initWithBytesNoCopy:characters length:utf32ByteCount encoding:encoding freeWhenDone:YES];
}
Это примерно в 3-4 раза быстрее, чем версия memcpy.Вышеупомянутая сущность была обновлена до последней версии кода.
Enumerate substrings: 2.168705
MemCopy: 0.488320
UTF-32: 0.150822
Enumerate substrings: 2.169655
MemCopy: 0.481786
UTF-32: 0.147534
Enumerate substrings: 2.248812
MemCopy: 0.505995
UTF-32: 0.154531