Reputation: 4196
I am searching through around 100k strings in a function:
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]];
}
}
where tf.text
is the user inputted text in a UITextField
. Performance is slow and I get the impression there is a better way of searching rather than a straight up string comparison anyway.
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.
Upvotes: 0
Views: 155
Reputation: 90531
A few obvious things:
searchStrings
property getter multiple times through the loop. Call it once and cache it in a local variable.count
getter on every loop iteration.text
getter on every loop iteration.lowercaseString
, don't call it on the text field's string on every loop iteration. But see the next item.lowercaseString
. Use -rangeOfString:options:
and the NSCaseInsensitiveSearch
option, -localizedCaseInsensitiveContainsString:
, or -localizedStandardContainsString:
. Not only are they likely to be faster, they're more correct. (Languages can be strange and comparing lowercased strings may not necessarily be the same as a case-insensitive comparison.)searchStrings
, you can use -indexesOfObjectsWithOptions:passingTest:
to build a set of the indexes of the matching elements. You don't have to write the (slower) enumeration code yourself in that case. You can also specify NSEnumerationConcurrent
in the options to allow the framework to use multiple threads to perform the search. After you have the index set, you would then use -objectsAtIndexes:
to get an array of the corresponding elements from formattedStrings
. Again, the framework can do that faster than your approach of building it up one element at a time in a mutable array. (Thanks to @rmaddy for the suggestion.)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.
I don't understand this part of your question and it seems like it's about correctness and not performance. So: 1) get correctness first before being concerned about performance. No point making a wrong algorithm faster. 2) It should be a separate question.
Upvotes: 2