我正在一个函数中搜索大约 100k 个字符串:
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”,因此如果在 attributeA 之前输入 attributeB,它不会作为结果出现,而它应该出现。
最佳答案
一些显而易见的事情:
- 不要在循环中多次调用
searchStrings
属性 getter。调用一次并将其缓存在局部变量中。 - 不要在每次循环迭代时调用
count
getter。 - 不要在每次循环迭代时调用
text
getter。 - 如果您要使用
lowercaseString
,请不要在每次循环迭代时都在文本字段的字符串上调用它。但请看下一项。 - 不要使用
lowercaseString
。使用-rangeOfString:options:
和NSCaseInsensitiveSearch
选项、-localizedCaseInsensitiveContainsString:
或-localizedStandardContainsString:
。它们不仅可能更快,而且更正确。 (语言可能很奇怪,比较小写字符串可能不一定与不区分大小写的比较相同。) - 由于您是根据
searchStrings
的匹配元素的索引构建一个数组,您可以使用-indexesOfObjectsWithOptions:passingTest:
来构建一组索引匹配的元素。在这种情况下,您不必自己编写(较慢的)枚举代码。您还可以在选项中指定NSEnumerationConcurrent
以允许框架使用多个线程来执行搜索。设置索引后,您可以使用-objectsAtIndexes:
从formattedStrings
中获取相应元素的数组。同样,框架可以比您在可变数组中一次构建一个元素的方法更快地完成这项工作。 (感谢@rmaddy 的建议。)
The strings being searched through are formatted like this: "attributeA attributeB attributeC", so if attributeB is entered before attributeA, it does not come up as a result, which it should.
我不明白你问题的这一部分,它似乎是关于正确性而不是性能。所以:1)在关注性能之前先获得正确性。让错误的算法更快是没有意义的。 2) 它应该是一个单独的问题。
关于ios - 提高 objective-c 中的搜索性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50825568/