Каков наилучший способ инициализации объекта NSMutableString? - PullRequest
15 голосов
/ 26 декабря 2011

Если я возьму следующий вопрос.Каков наилучший способ инициализации класса NSMutableString?(Все экземпляры будут возвращаться в неожиданное время ... поэтому я буду считать, что инициализация выполняется следующим образом:)

  1. Если я заранее знаю объем работы.(ожидается)

    NSMutableString *str1 = [NSMutableString stringWithString:@""];
    NSMutableString *str2 = [NSMutableString stringWithCapacity:0];
    NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];
    NSMutableString *str4 = [NSMutableString string];
    
    for(int i = 0; i< 1000; i++)
    {
        //The following tasks.(Adding to the string to continue working.)
        [/*str1~str4*/ appendFormat:@"%d", i];
    }
    
  2. Если я заранее не знаю объем работы.(неожиданно)

    NSMutableString *str1 = [NSMutableString stringWithString:@""];
    NSMutableString *str2 = [NSMutableString stringWithCapacity:0];
    NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];
    NSMutableString *str4 = [NSMutableString string];
    
    for(int i = 0; i< /*a large of size(unpredictable)*/ ; i++)
    {
        //The following tasks.(Adding to the string to continue working.)
        [/*str1~str4*/ appendFormat:@"%d", i];
    }
    

При выполнении этих задач в значительной степени разделиться на две части. Каков наилучший способ инициализации?

Я иногда при работе с этими задачами тоже путаюсь.

Ответы [ 6 ]

13 голосов
/ 27 декабря 2011

Случай 1

Из перечисленных вариантов я бы использовал:

NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];

… если вы знаете размер пункта назначения или оцените его с небольшимкомната в верхней части и могут быстро определить точный размер или сценарий размера наихудшего случая, это может сэкономить несколько операций перераспределения и копирования.Если вы не знаете размер в худшем случае или если для его расчета требуется много времени, то вы также можете использовать [NSMutableString string] или [NSMutableString new].Кроме того, *WithCapacity - это подсказка, которую платформы могут игнорировать.

Конечно, тело вашего цикла и размер, который вы резервируете, также подразумевают, что все значения равны [0… 9] (в частности,, что все значения потребляют один символ), и в этом случае вы, вероятно, могли бы добиться большего успеха, используя строки формата с большим количеством аргументов.Однако i явно больше 9 для большинства итераций и потребляет в среднем по 3 символа каждый, поэтому 3000 будет более подходящей резервной емкостью для точного отправленного вами кода.

Случай 2

Из перечисленных опций я бы использовал:

NSMutableString *str4 = [NSMutableString string];

Еще лучше, если вам не нужно добавлять его в пул автоматического выпуска: [NSMutableString new] или [[NSMutableString alloc] init].

Другие примечания

Да, исключение объектов из пулов автоматического выпуска (например, использование alloc + init) может повысить производительность и значительно снизить пиковое использование памяти.Иногда это не зависит от вас, а в некоторых средах (например, ARC) это может произойти, даже если вы используете удобный автоматический конструктор - например, [NSMutableString string].

Более быстрое решение

Наконец, если описанный вами случай действительно является проблемой производительности, самым быстрым способом было бы создать буфер char в стеке, а затем создать один NSString из результата копирования чисел вchar буфер.Предполагая, что все ваши int равны 0-9, это будет очень быстро и просто, а затем просто создайте NSString из (прекращенной) строки.Вы даже можете сделать это, если размер входного файла изменяется или очень велик (в результате получается очень длинная строка).

10 голосов
/ 26 декабря 2011

Это не имеет значения.

Если вы уже оптимизировали свою программу, чтобы это решение оказало ощутимое влияние на ее общую производительность, похлопайте себя по спине или, как сказал бы Шелдон из BBT, «есть шоколад!»

PS:
Если вы точно знаете размер заранее или действительно хорошо оценили его, то используйте этот размер в stringWithCapacity: или initWithCapacity:, если нет, тогда даже не беспокойтесь - пусть структура решит, это чертовски умно !

4 голосов
/ 20 марта 2014

Вот кратчайший путь:

NSMutableString *string = [@"" mutableCopy];
1 голос
/ 05 августа 2014
NSMutableString *str1 = [NSMutableString stringWithString:@""];

Плохо, строка NSString (@ "") создается бессмысленно, а затем копируется в новую строку NSMutable

NSMutableString *str2 = [NSMutableString stringWithCapacity:0];

Плохо, NSMutableString с емкостью 0 нужно будет раздувать при первом добавлении к нему.

NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];

Хорошо, если 1000 имеет какое-то значение (т. Е. Это ожидаемый размер для контента, с которым вы работаете).

NSMutableString *str4 = [NSMutableString string];

Хорошо, используя удобный метод, который похож на [NSMutableString alloc] init];

0 голосов
/ 26 декабря 2011

Всегда лучше выделить и инициализировать объект, а не использовать метод класса для его создания (который помещает его в ближайший пул автоматического выпуска).

Итак,

NSMutableString* stringOne = [[NSMutableString alloc] initWithCapacity:capacity];

вместо

NSMutableString* stringTwo = [NSMutableString stringWithCapacity:capacity];

Просто помните, что вы должны освободить stringOne, когда закончите с ним, но не stringTwo, потому что метод stringWithCapacity: class возвращает автоматически выпущенный объект.

Подробнее о теме читайте здесь: http://www.mulle -kybernetik.com / artikel / Optimization / opti-5.html

0 голосов
/ 26 декабря 2011

Если вы знаете размер заранее, используйте

 [NSMutableString stringWithCapacity: _Known_Size_];

Если вы не знаете размер заранее, используйте

 [NSMutableString stringWithCapacity: _small_number_];

Тогда изменяемая строка будет расти по мере необходимостик.

...