Re: Fast NSArray compare
Re: Fast NSArray compare
- Subject: Re: Fast NSArray compare
- From: Ken Thomases <email@hidden>
- Date: Mon, 14 Apr 2014 21:01:42 -0500
On Apr 14, 2014, at 7:02 PM, Varun Chandramohan wrote:
> I have a question about efficiency when trying to compare NSURL. The requirement is quite simple. I try and iterate through a directory to all subdirectories and files. While doing this walk-through, I need to check against an array of NSURLs which are restricted files and folders.
> This means if I find a match of file I am trying to access in the array then I don't do any operations on that file and continue.
You don't say how you're comparing URLs. Just in case, you should not use -[NSURL isEqual:] or any method which relies on string comparison. That can be confused by case differences, the presence of hard or symbolic links, and extraneous path elements (e.g. "foo/./bar" vs. "foo/bar").
You should obtain the resource identifier object of each URL using -getResourceValue:forKey:error: with NSURLFileResourceIdentifierKey, then compare those two objects using -isEqual:.
If you take Graham's suggestion of using an NSSet or similar hash-based collection to test, then put the resource identifiers of the restricted files into the set and check a candidate URL's resource identifier against that set.
For what it's worth, comparing resource identifiers may be faster than the string comparison otherwise inherent in -[NSURL isEqual:]. The identifier is likely to be a number or pair of numbers internally and so is quick to compare. That said, the improvement may be swamped by the cost of obtaining the resource identifier object.
> Secondly, I plan to store array of NSURL for restricted files and folders. What is the best way to get partial compare?
>
> Eg: Entry in array : /XYZ/abc
> This means I should not iterate into the abc folder. So any files /XYZ/abc/1.c or /XYZ/abc/def/2.c should all be skipped. Whats the best way to do partial NSURL compare? Or is it better I store it as NSString instead of NSURL?
Don't try to do substring compares. Since you're iterating a directory hierarchy, you should simply not iterate a subdirectory if it matches. When using NSDirectoryEnumerator, that's easy to do: just call -skipDescendants.
If you feel you must compare two URLs to see if one is contained in the other, you'll probably have to successively obtain the parent directory URL from the candidate URL using -getResourceValue:forKey:error: with NSURLParentDirectoryURLKey until you've reached the top of the hierarchy or you have matched one of your restricted file URLs.
You _might_ want to optimize that by obtaining the NSURLVolumeIdentifierKey of each URL and then determining that one doesn't contain the other if the two URLs are for different volumes. Whether that's appropriate or not depends on whether you care about path-based containment or file-system-based containment. "/foo/bar/baz" may be on a different volume than "/foo" and you have to decide whether that means that it's not contained by "/foo".
Regards,
Ken
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden