NSOrderedSet seems to be able to give O(1) lookup speed of hash-tables and array like ordering of objects? What is the data structure used to achieve this? Is it a combination of two, e.g: Hashtable and a separate Array where index i has the key corresponding to it's object in the Hashtable?
We don't know how Apple chose to implement this data structure. The only way to find out would be to reverse-engineer the Foundation framework. But this is not an useful thing to do, Apple could change the implementation and underlying data structure with every update. So relying on this for a production app would be very stupid since it could break the app at any time.
If you wanted to implement this yourself your approach with a hash table and an array will work. The best way would be to store the objects in the array and have the hash map store the array indices keyed by objects.
Of course there are other possible ways how this could be implemented with different performance characteristics. It could be just an array making the containsObject: test O(n), or it could just be a hash table (with the object as key and index as value) making the objectAtIndex: operation O(n).
Related
I have complex data structure, mostly made up of NSDictionaries, generated by NSJSONSerialization reading a large JSON file. Now, the dictionaries in such structure, use all the same keys. Would it be safe to assume that the ordering of the keys is the same in all dictionaries? My gut would tell me so, but it really depends on the implementation, I guess.
Cheers,
My gut would say no. What I don't know is if there is a type of "order by" method that you could call. You may want to store keys in an array, then use that for your ordering to pull from the dictionary.
Look here as well:
https://stackoverflow.com/a/1295472/546237
My program should save, retrieve and manipulate a large load of data. (Around 200,000 entries, which all have around 20 entries.)
I'm wondering how I should implement the data: create my own class, use a struct or use NSDictionary.
The whole data would be saved in an array (for going through the whole data). But since performance matters (particularly the searching part) I would like to chose the fastest and savest way.
Any suggestions?
CoreData with sqlite store type is the way. You'd be able to fetch portions of data without reading the whole thing to the memory at once. This way you'd be able to generate custom NSManagedObject subclasses if you'd need custom behavior for each instance of an object.
Since you can not access element of the NSMutableSet randomly, does this mean it is implemented like a linked list?
I.e. will it have faster insertion / deletion than a NSMutableArray?
The source code is available, so you can have a look: CFSet.c . (This is a Core Foundation counterpart to NSSet, but they are basically the same.) It's a hash table.
But you should also bear in mind that NSArray is, in fact, not implemented as an array. You can see the implementation here: CFArray.c. Maybe this blog article is easier to understand, although it's a bit dated (~5 years.)
No. Lookup time will be faster because it will use hashes.
I am no Objective-C progammer, but usually sets are implemented through hash-tables, which (if properly done) will yield O(1) for insert, delete and lookup.
Technically, hashes typically give you O(M), where M is the size of the key, but for a set you would simply use the id of the key object, which is constant, so you're back to O(1).
Sets are normally implemented with balanced binary search trees (e.g. red-black trees, avl trees).
I'm refactoring a project that involves passing around a lot of arrays. Currently, each method that returns an array sorts it right before returning it. This isn't ideal for a couple reasons -- there's lots of duplicated code, it's inefficient to sort an array two or three times, and it's too easy to write a new function but to forget to sort the array before returning it.
I'm looking for a way to guarantee that the array always kept in alphabetical order. My current thought is to subclass NSMutableArray and/or NSArray to create an alphabetized array class. I would need to override all of the methods that create or modify the array to call super and then sort itself.
Does this sound reasonable, or is there a better approach?
EDIT:
Since performance issues have been mentioned, I'll include the relevant information from my project. Speed is not an important concern. The whole process only takes a few seconds, and the tool is only used every so often. So simplicity and obvious correctness is more important.
Also, the use case for arrays is specific. When an array is returned, the caller always accesses every element in the array at least once.
A balanced binary tree is the standard and efficient way to keep items sorted. Almost any way to do random access with a plain array will be slow. A skip list is also efficient and you may be able to add the functionality to the array class.
Check out CHDataStructures. It's a framework that has a lot of self-sorting datastructures, like balanced binary trees and whatnot.
This is really a three-part question, but I've answered the first question myself:
I'm working on the iPhone, with many objects (up to 200) on the screen. Each object needs to look if it's overlapping other objects, and act accordingly. My original naive implementation was for each object to run through the list of each other object to check their bounding boxes (using CGRectInsersectsRect).
So my question (and answer) is what's a better method? My new implementation is to sort the array every frame using an insertion sort (since the data will be mostly sorted already) on the y-position of each object, then check only the nearest object on either side of the one searching, to see if it's in range vertically, then check horizontally.
First question: Is insertion sort the method I want to use for an array of objects that tend to move around randomly but only to a small extent so they mostly stay in order based on the last frame? Also: what sort algorithm does the NSArray use when I call
- sortedArrayUsingSelector:
I would sort of assume that it uses a quick sort, since it's the most useful in the general case. Does anybody know if I'm wrong? Does anybody know if I can change the sort method or if I will have to write my own sorting function?
Second question: is there a function for retrieving items from a sorted array using a binary search, rather than the naive approach that I assume is used by
- indexOfObject:
or would I have to write my own?
NSArray uses many different data structures internally depending on how many objects are in the array. See a Peter Ammon blog entry for more information. But basically this means you can't expect a certain kind of sort to happen. Sometimes it is worth it to write your own array implementation using C arrays so you can control the sorts yourself.
There are definitely much faster ways to implement collision detection. Look into Bounding Volume Hierarchies like KD Trees or similar.
As far as I know indexOfObject: is the only way, but it's potentially not as dumb as you think. Everything is hashable for NSDictionary so they can use some of those smarts in NSArray.