Улучшить производительность поиска в target-c - PullRequest
0 голосов
/ 12 июня 2018

Я ищу около 100 тыс. Строк в функции:

results = [NSMutableArray new];
for (int n = 0; n < (int)_donkey.searchStrings.count; n++){
    if ([[_donkey.searchStrings[n] lowercaseString] rangeOfString:tf.text.lowercaseString].location != NSNotFound){
        [results addObject:_donkey.formattedStrings[n]];
    }
}

, где tf.text - это введенный пользователем текст в UITextField.Производительность медленная, и у меня складывается впечатление, что есть лучший способ поиска, чем прямое сравнение строк в любом случае.

Строки, по которым производится поиск, имеют следующий формат: "attributeA attributeB attributeC", поэтому, если attributeB вводится перед attributeA, в результате он не появляется, что и должно быть.

1 Ответ

0 голосов
/ 13 июня 2018

Несколько очевидных вещей:

  • Не вызывайте метод получения свойства searchStrings несколько раз в цикле.Вызовите его один раз и кэшируйте в локальной переменной.
  • Не вызывайте геттер count на каждой итерации цикла.
  • Не вызывайте геттер text на каждой итерации цикла.
  • Если вы собираетесь использовать lowercaseString, не вызывайте его в строке текстового поля на каждой итерации цикла.Но смотрите следующий пункт.
  • Не используйте lowercaseString.Используйте -rangeOfString:options: и параметр NSCaseInsensitiveSearch, -localizedCaseInsensitiveContainsString: или -localizedStandardContainsString:.Мало того, что они могут быть быстрее, они более правильные.(Языки могут быть странными, и сравнение строк в нижнем регистре не обязательно должно быть таким же, как сравнение без учета регистра).
  • Поскольку вы строите массив из индексов соответствующих элементов searchStrings, вы можетеиспользуйте -indexesOfObjectsWithOptions:passingTest: для построения набора индексов соответствующих элементов.В этом случае вам не нужно самостоятельно писать (более медленный) код перечисления.Вы также можете указать NSEnumerationConcurrent в параметрах, чтобы платформа могла использовать несколько потоков для выполнения поиска.После того, как вы установили индекс, вы должны использовать -objectsAtIndexes:, чтобы получить массив соответствующих элементов из formattedStrings.Опять же, фреймворк может сделать это быстрее, чем ваш подход к созданию по одному элементу за раз в изменчивом массиве.(Спасибо @rmaddy за предложение.)

Строки, по которым выполняется поиск, отформатированы следующим образом: "attributeA attributeB attributeC", поэтому, если attributeB вводится перед attributeA, он не приходитв результате, что и должно быть.

Я не понимаю эту часть вашего вопроса, и похоже, что речь идет о правильности, а не производительности.Итак: 1) сначала получите правильность, прежде чем беспокоиться о производительности.Нет смысла делать неправильный алгоритм быстрее.2) Это должен быть отдельный вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...