NSSearchField latency and performance (was: configuring cancel action)
NSSearchField latency and performance (was: configuring cancel action)
- Subject: NSSearchField latency and performance (was: configuring cancel action)
- From: Nicko van Someren <email@hidden>
- Date: Mon, 20 Feb 2006 15:27:55 +0000
On 19 Feb 2006, at 18:34, Karim Morsy wrote:
one more questions on searchfields: I've activated "sends search
string immediately" in Interface builder.
however, there's an annoying latency as I enter letters in the
searchfield. I use the following method to search for key words in
a table view that consists of 2 columns:
while (anObject = [enumerator nextObject]) {
...
if(range1.location == NSNotFound && range2.location == NSNotFound )
...
}
obviously this is not the best way to do it. can anybody suggest a
better and especially faster way to do it ?
Two things spring to mind to help fix this. Firstly, you could set
up your search to happen on it's own thread. In this case you'd have
the action take a lock on the search value, write the new value,
release the lock and wake the search thread if it's not started and
then in your search thread you could have an outer loop which checks
the search field, sleeps if there is nothing to search on and does a
search if there is.
The second thing to do would be to build an index, so that your
searches are faster. The cost and efficiency of this is pretty data
dependant but for searching through large numbers of short bits of
text the following method works pretty well:
Create an NSMutableDictionary for the index
For each item in the set of data:
(Optionally force the data into uppercase and/or strip accents)
Add a leading space to the string
For each pair of characters in the string:
If the second character is not whitespace:
Look up the character pair as a key the index dictionary
If the key does not exist:
Create an NSMutableSet and add it under that key
Add the data object to the Set for the given key
In order to search the index you pre-filter as follows:
(Optionally force case and strip accents)
Look up in the index dictionary the key formed from a single space
and the initial letter of the search
If the key does not exist:
return Null
else:
Make a mutable copy of the set
For each pair of characters in the string:
If the second character is not whitespace:
Look up the character pair as a key in the index dictionary
If the key does not exist:
return Null
else:
call intersectSet: on the initial copy with the set given under
the key
Now you can either return the copied working set or you can iterate
over that set to perform more comprehensive tests
There are millions of variants on this theme (the most obvious being
to use triples rather than pairs of letters) but this model is pretty
easy to implement using the primitives provided in Cocoa and is
fairly efficient for modest sized sets of data. Furthermore, since
it only uses classes that conform to the NSCoding protocol you can
pack up the index with an NS(Keyed)Archiver along with the rest of
your data when you save it to a file.
Of course the other option to improving your search speed would be to
use CoreData, but that might mean re-architecting your application.
Cheers,
Nicko
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden